Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions SVProgressHUD.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ Pod::Spec.new do |s|

s.subspec 'Core' do |core|
core.source_files = 'SVProgressHUD/*.{h,m}'
core.resources = ['SVProgressHUD/SVProgressHUD.bundle']
core.resources = ['SVProgressHUD/SVProgressHUD.bundle/**']
core.resource_bundles = {'SVProgressHUD' => ['SVProgressHUD/PrivacyInfo.xcprivacy']}
end

s.subspec 'AppExtension' do |ext|
ext.source_files = 'SVProgressHUD/*.{h,m}'
ext.resources = ['SVProgressHUD/SVProgressHUD.bundle']
ext.resources = ['SVProgressHUD/SVProgressHUD.bundle/**']
ext.resource_bundles = {'AppExtension' => ['SVProgressHUD/PrivacyInfo.xcprivacy']}
ext.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'SV_APP_EXTENSIONS=1' }
end
Expand Down
152 changes: 92 additions & 60 deletions SVProgressHUD/SVProgressHUD.m
Original file line number Diff line number Diff line change
Expand Up @@ -78,54 +78,77 @@ + (SVProgressHUD*)sharedView {

#if !defined(SV_APP_EXTENSIONS)
+ (UIWindow *)mainWindow {
UIApplication *sharedApplication = [UIApplication sharedApplication];
__block UIWindow *mainWindow = nil;
if (@available(iOS 13.0, tvOS 13.0, *)) {
[sharedApplication.connectedScenes enumerateObjectsUsingBlock:^(UIScene *scene, BOOL *stop1) {
if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:UIWindowScene.class]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
[windowScene.windows enumerateObjectsUsingBlock:^(UIWindow *window, NSUInteger idx, BOOL *stop2) {
// First pass: find key window in active foreground app scenes
for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) {
if (![scene isKindOfClass:[UIWindowScene class]]) {
continue;
}

UIWindowScene *windowScene = (UIWindowScene *)scene;
if (windowScene.activationState == UISceneActivationStateForegroundActive &&
[windowScene.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
for (UIWindow *window in windowScene.windows) {
if (window.isKeyWindow && !window.isHidden) {
mainWindow = window;
*stop1 = YES;
*stop2 = YES;
return window;
}
}];
}
if (windowScene.windows.count > 0) {
return windowScene.windows.firstObject;
}
}
}];
}
if (!mainWindow) {
[sharedApplication.windows enumerateObjectsUsingBlock:^(UIWindow *window, NSUInteger idx, BOOL *stop) {
}

// Second pass: any app scene regardless of activation state
for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) {
if (![scene isKindOfClass:[UIWindowScene class]]) {
continue;
}

UIWindowScene *windowScene = (UIWindowScene *)scene;
if (![windowScene.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
continue;
}

for (UIWindow *window in windowScene.windows) {
if (window.isKeyWindow && !window.isHidden) {
return window;
}
}
if (windowScene.windows.count > 0) {
return windowScene.windows.firstObject;
}
}

// Third pass: check all application windows
for (UIWindow *window in [UIApplication sharedApplication].windows) {
if (window.isKeyWindow && !window.isHidden) {
mainWindow = window;
*stop = YES;
return window;
}
}];
}
// delegate window
if (!mainWindow) {
if (@available(iOS 13.0, tvOS 13.0, *)) {
[sharedApplication.connectedScenes enumerateObjectsUsingBlock:^(UIScene *scene, BOOL *stop) {
if ([scene isKindOfClass:UIWindowScene.class] && [scene.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
if ([windowScene.delegate conformsToProtocol:@protocol(UIWindowSceneDelegate)]) {
id<UIWindowSceneDelegate> sceneDelegate = (id<UIWindowSceneDelegate>)windowScene.delegate;
if (sceneDelegate.window) {
mainWindow = sceneDelegate.window;
*stop = YES;
}
}

// Fourth pass: delegate windows
for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) {
if ([scene isKindOfClass:[UIWindowScene class]] &&
[scene.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
if ([windowScene.delegate conformsToProtocol:@protocol(UIWindowSceneDelegate)]) {
id<UIWindowSceneDelegate> sceneDelegate = (id<UIWindowSceneDelegate>)windowScene.delegate;
if (sceneDelegate.window) {
return sceneDelegate.window;
}
}
}];
}
if (!mainWindow) {
id<UIApplicationDelegate> appDelegate = sharedApplication.delegate;
if ([appDelegate respondsToSelector:@selector(window)]) {
mainWindow = appDelegate.window;
}
}
}
return mainWindow;

// Pre-iOS 13 fallback / last resort
id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
if ([appDelegate respondsToSelector:@selector(window)] && appDelegate.window) {
return appDelegate.window;
}

return nil;
}
#endif

Expand All @@ -135,11 +158,12 @@ + (NSBundle *)imageBundle {
#else
NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]];
#endif
NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"];
/*NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"];
if (!url) {
return nil;
}
return [NSBundle bundleWithURL:url];
return [NSBundle bundleWithURL:url];*/
return bundle;
}

#pragma mark - Setters
Expand Down Expand Up @@ -554,9 +578,8 @@ - (void)updateMotionEffectForXMotionEffectType:(UIInterpolatingMotionEffectType)

- (void)updateViewHierarchy {
// Add the overlay to the application window if necessary
if(!self.controlView.superview) {
// Check if containerView is set and still in the view hierarchy
if(self.containerView && self.containerView.window){
if (!self.controlView.superview) {
if (self.containerView && self.containerView.window) {
[self.containerView addSubview:self.controlView];
} else {
#if !defined(SV_APP_EXTENSIONS)
Expand All @@ -566,7 +589,7 @@ - (void)updateViewHierarchy {
}
#else
// If SVProgressHUD is used inside an app extension add it to the given view
if(self.viewForExtension) {
if (self.viewForExtension) {
[self.viewForExtension addSubview:self.controlView];
}
#endif
Expand Down Expand Up @@ -766,7 +789,7 @@ - (void)controlViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent*)event {

- (void)showProgress:(float)progress status:(NSString*)status {
__weak SVProgressHUD *weakSelf = self;
void (^block)(void) = ^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
__strong SVProgressHUD *strongSelf = weakSelf;
if(strongSelf){
if(strongSelf.fadeOutTimer) {
Expand Down Expand Up @@ -839,12 +862,7 @@ - (void)showProgress:(float)progress status:(NSString*)status {
[strongSelf.hapticGenerator prepare];
#endif
}
};
if ([NSThread isMainThread]) {
block();
} else {
[[NSOperationQueue mainQueue] addOperationWithBlock:block];
}
}];
}

- (void)showImage:(UIImage*)image status:(NSString*)status duration:(NSTimeInterval)duration {
Expand Down Expand Up @@ -1367,7 +1385,7 @@ - (CGFloat)visibleKeyboardHeight {
if (@available(iOS 13.0, tvOS 13.0, *)) {
for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
// only handle UIWindowScene
if ([scene isKindOfClass:[UIWindowScene class]]) {
if ([scene isKindOfClass:[UIWindowScene class]] && [scene.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
for (UIWindow *testWindow in ((UIWindowScene *)scene).windows) {
if(![testWindow.class isEqual:UIWindow.class]) {
keyboardWindow = testWindow;
Expand All @@ -1379,6 +1397,22 @@ - (CGFloat)visibleKeyboardHeight {
break;
}
}
if (keyboardWindow == nil) {
for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
// only handle UIWindowScene
if ([scene isKindOfClass:[UIWindowScene class]]) {
for (UIWindow *testWindow in ((UIWindowScene *)scene).windows) {
if(![testWindow.class isEqual:UIWindow.class]) {
keyboardWindow = testWindow;
break;
}
}
}
if (keyboardWindow != nil) {
break;
}
}
}
}

// Fallback to the old method if not iOS 13+ or if no window is found in a multi-scene environment
Expand Down Expand Up @@ -1419,15 +1453,13 @@ - (UIWindow *)frontWindow {
// For iOS 13 and later, we first find the active scene.
if (@available(iOS 13.0, tvOS 13.0, *)) {
for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive) {
if ([scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
for (UIWindow *window in windowScene.windows) {
// The isKeyWindow property is often a reliable way to find the main window,
// but we also check other properties for robustness.
if (window.isKeyWindow && window.alpha > 0) {
return window;
}
if (scene.activationState == UISceneActivationStateForegroundActive &&
[scene isKindOfClass:[UIWindowScene class]] &&
[scene.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
for (UIWindow *window in windowScene.windows) {
if (window.isKeyWindow && window.alpha > 0) {
return window;
}
}
}
Expand Down