最近发现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;
}
网友评论