iOS13 SVProgressHUD在SceneDelegate模式下显示在左上角

最近发现Toast弹窗-第三方库SVProgressHUD在iOS13+的手机上跑,并且用了SceneDelegate创建window的模式下会显示异常,显示在屏幕左上角。另外弹出toast后,用户交互也关不掉(可以点击页面内其他的交互)。
升级了最新的SVProgressHUD版本,并没有解决问题。想到应该是源码中,toast view添加到window时没有判断SceneDelegate创建window的情况。
修改SVProgressHUD.m的源码:
1.设置HUD的frame设置

- (void)positionHUD:(NSNotification*)notification {
    CGFloat keyboardHeight = 0.0f;
    double animationDuration = 0.0;

#if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS
    
    //*********************************加的代码(修复iOS13上找不到keyWindow)*********************************//
    UIWindow *keyWindow = [self getKeyWindow];
    self.frame = keyWindow.bounds;
    UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation;
#elif !defined(SV_APP_EXTENSIONS) && !TARGET_OS_IOS
    self.frame= [UIApplication sharedApplication].keyWindow.bounds;
#else
    if (self.viewForExtension) {
        self.frame = self.viewForExtension.frame;
    } else {
        self.frame = UIScreen.mainScreen.bounds;
    }
#if TARGET_OS_IOS
    UIInterfaceOrientation orientation = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait;
#endif
#endif
...
...
...

2.controlView的frame设置

- (UIControl*)controlView {
    if(!_controlView) {
        _controlView = [UIControl new];
        _controlView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _controlView.backgroundColor = [UIColor clearColor];
        _controlView.userInteractionEnabled = YES;
        [_controlView addTarget:self action:@selector(controlViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown];
    }
    
    // Update frames
#if !defined(SV_APP_EXTENSIONS)
    //*********************************加的代码(修复iOS13上找不到keyWindow)*********************************//
    UIWindow *keyWindow = [self getKeyWindow];
    CGRect windowBounds = keyWindow.bounds;
    _controlView.frame = windowBounds;
#else
    _controlView.frame = [UIScreen mainScreen].bounds;
#endif
    
    return _controlView;
}

3.keyboardWindow键盘高度的判断

#pragma mark - Helper
    
- (CGFloat)visibleKeyboardHeight {
#if !defined(SV_APP_EXTENSIONS)
    UIWindow *keyboardWindow = nil;
    NSArray *windows = nil;
    if (@available(iOS 13.0, *)){
        for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) {
            if ([windowScene isKindOfClass:UIWindowScene.class]) {
                windows = windowScene.windows;
                break;
            }
        }
    }else {
        windows = UIApplication.sharedApplication.windows;
    }
    for (UIWindow *testWindow in windows) {
        if(![testWindow.class isEqual:UIWindow.class]) {
            keyboardWindow = testWindow;
            break;
        }
    }
    
    for (__strong UIView *possibleKeyboard in keyboardWindow.subviews) {
        NSString *viewName = NSStringFromClass(possibleKeyboard.class);
        if([viewName hasPrefix:@"UI"]){
            if([viewName hasSuffix:@"PeripheralHostView"] || [viewName hasSuffix:@"Keyboard"]){
                return CGRectGetHeight(possibleKeyboard.bounds);
            } else if ([viewName hasSuffix:@"InputSetContainerView"]){
                for (__strong UIView *possibleKeyboardSubview in possibleKeyboard.subviews) {
                    viewName = NSStringFromClass(possibleKeyboardSubview.class);
                    if([viewName hasPrefix:@"UI"] && [viewName hasSuffix:@"InputSetHostView"]) {
                        CGRect convertedRect = [possibleKeyboard convertRect:possibleKeyboardSubview.frame toView:self];
                        CGRect intersectedRect = CGRectIntersection(convertedRect, self.bounds);
                        if (!CGRectIsNull(intersectedRect)) {
                            return CGRectGetHeight(intersectedRect);
                        }
                    }
                }
            }
        }
    }
#endif
    return 0;
}

4.getKeyWindow方法

- (UIWindow *)getKeyWindow
{
    UIWindow *keyWindow = nil;
    if (@available(iOS 13.0, *)){
        for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) {
            if ([windowScene isKindOfClass:UIWindowScene.class]) {
                for (UIWindow *window in windowScene.windows) {
                    if (window.isKeyWindow) {
                        keyWindow = window;
                        break;
                    }
                }
            }
        }
    }else {
        keyWindow = [[[UIApplication sharedApplication] delegate] window];
    }
    
    return keyWindow;
}

你可能感兴趣的:(iOS13 SVProgressHUD在SceneDelegate模式下显示在左上角)