美文网首页
iOS 13适配填坑总结

iOS 13适配填坑总结

作者: Hedgehog___ | 来源:发表于2019-10-30 11:58 被阅读0次

前言

  前段时间苹果发布了最新系统iOS 13,开发者当然避免不了去适配最新的系统版本,以下我总结了在适配过程中遇到的问题以及坑。

1、获取当前控制器

  我在适配iOS 13之前获取当前控制器的方法是这样的

- (UIViewController *)currentViewController {
   UIViewController *result = nil;
    UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
    if (keyWindow.windowLevel != UIWindowLevelNormal) {
        NSArray *windows = [UIApplication sharedApplication].windows;
        for (UIWindow *tempWindow in windows) {
            if (tempWindow.windowLevel == UIWindowLevelNormal) {
               keyWindow = tempWindow;
                 break;
             }
         }
     }
   id nextResponder = [[keyWindow.subviews firstObject] nextResponder];
    if ([nextResponder isKindOfClass:[UITabBarController class]]) {
        UITabBarController *tabBarController = (UITabBarController*)nextResponder;
        result = tabBarController.selectedViewController;
       if ([result isKindOfClass:[UINavigationController class]]) {
            UINavigationController *naviC = (UINavigationController*)result;
            result = naviC.visibleViewController;
         }
    } else if ([nextResponder isKindOfClass:[UINavigationController class]]) {
        UINavigationController *naviC = (UINavigationController*)nextResponder;
        result = naviC.visibleViewController;
    } else if ([nextResponder isKindOfClass:[UIViewController class]]) {
        result = (UIViewController*)nextResponder;
   } else {
        result = keyWindow.rootViewController;
     }
     
    return result;
 }

打断点发现:

image.png
keywindownextResponder居然在iOS 13 中居然也变成了UIWindow
所以我们可以通过绕过nextResponder来获取当前控制器:
-(UIViewController *)currentViewController{
    UIWindow *window = [UIApplication sharedApplication].delegate.window;
    NSLog(@"window level: %.0f", window.windowLevel);
    if (window.windowLevel != UIWindowLevelNormal) {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for (UIWindow * tmpWin in windows) {
            if (tmpWin.windowLevel == UIWindowLevelNormal) {
                window = tmpWin;
                break;
            }
        }
    }
    
    //从根控制器开始查找
    UIViewController *rootVC = window.rootViewController;
    UIViewController *activityVC = nil;
    
    while (true) {
        if ([rootVC isKindOfClass:[UINavigationController class]]) {
            activityVC = [(UINavigationController *)rootVC visibleViewController];
        } else if ([rootVC isKindOfClass:[UITabBarController class]]) {
            activityVC = [(UITabBarController *)rootVC selectedViewController];
        } else if (rootVC.presentedViewController) {
            activityVC = rootVC.presentedViewController;
        }else {
            break;
        }
        
        rootVC = activityVC;
    }
    
    return activityVC;
}

解决。

2、UIWebView的执行JS脚本方法回调线程问题

  在iOS 13之前中用JSContext执行脚本方法回调的block是在主线程的,可以之间在里面修改UI布局,但是在iOS 13中突然就崩溃了,我在调试中发现了这个回调block居然不在主线程了,崩溃的原因也是因此。

image.png
image.png

临时解决方法是加一个安全线程的调用:

#define dispatch_main_async_safe(block)\
    if ([NSThread isMainThread]) {\
        block();\
    } else {\
        dispatch_async(dispatch_get_main_queue(), block);\
    }

首先声明这个方法只是临时阻止UIWebViewcrash的一种临时方法,本人并不建议这么做,更好的的方法是更换WKWebView,因为UIWebView在iOS 12就已经被废弃。

image.png
3、暗黑模式(Dark Model)

两种方法:
1)直接全局关闭暗黑模式(不建议)
info.plist中加入:key 为User Interface Style value类型为String值为Light可直接全局禁用暗黑模式
2)根据风格适配
我借鉴了这篇文章

4、UIViewController的UIModalPresentationStyle属性

在iOS 13未适配的时候突然发现present出来的控制器样式变了,在查看了相关属性的情况之后发现了UIModalPresentationStyle新增了一个枚举值UIModalPresentationAutomatic在iOS 13之后控制的默认值就是这个,要想恢复之前的模态跳转样式需要设置控制器UIModalPresentationStyleUIModalPresentationFullScreen就好:

if (@available(iOS 13.0, *)) {//iOS 13 默认不使用 UIModalPresentationFullScreen 模式
            self.modalPresentationStyle =  UIModalPresentationFullScreen; 
}
5、UITextField的leftview

在iOS 13中突然发现我的UITextfield leftview显示有点怪,然后发现如果直接给 textfield.leftView 赋值一个 UILabel 对象,他的宽高会被 sizeToFit。解决方法:给label套一层UIView的父视图在设置leftview。解决

6、Push推送获取的token的变化

在iOS 13的系统版本中,token的格式发生了变得,导致不能按照iOS13之前的处理方法去处理然后再上传服务器。

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    DBLOG_FUN;
   NSString *_deviceToken = @"";
   if (@available(iOS 13.0, *)) {
      if (![deviceToken isKindOfClass:[NSData class]]) return;
      const unsigned *tokenBytes = [deviceToken bytes];
      _deviceToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                            ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                            ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                            ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
      [[DataStore sharedStore] setDeviceToken:_deviceToken];
      DBLOG(@"_deviceToken:%@", _deviceToken);
   }else if([deviceToken.description length] > 0) {
        NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"<>"];
        _deviceToken = [deviceToken.description stringByTrimmingCharactersInSet:set];
        _deviceToken = [_deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
        [[DataStore sharedStore] setDeviceToken:_deviceToken];
        DBLOG(@"_deviceToken:%@", _deviceToken);
    }
}
7、UITextfield通过KVC修改placeholderlabel方法

在iOS 13中通过以下方法修改UITextfield的placeholder会发生crash:

// 使用的私有方法
[_textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];

解决方法有两种:
1)把前面的下划线去掉(不建议)

[_textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];

2)通过attributedPlaceholder设置(建议)

_textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"输入"attributes:@{NSForegroundColorAttributeName: [UIColor redColor]}];
待续。。。

相关文章

  • iOS13适配

    参考: iOS13 适配踩坑 - 持续更新 iOS 13 适配要点总结 iOS 13 适配要点总结 1、prese...

  • iOS 13适配填坑总结

    前言   前段时间苹果发布了最新系统iOS 13,开发者当然避免不了去适配最新的系统版本,以下我总结了在适配过程中...

  • iOS 13 适配要点总结(转)

    转自: iOS 13 适配要点总结 iOS 13适配

  • iOS13适配

    最新iOS13适配填坑记录如下: 1.私有API被封禁(KVC限制),禁止访问。 iOS13中通过KVC方式来获取...

  • 适配iOS 13填坑

    使用苹果私有API 获取UISearchBar的_searchField对象 改UITextField的place...

  • 2019-09-20

    iOS 13 适配要点总结 - 简书 iOS 13 适配 ING... - 简书 Xcode11新建项目后的一些问...

  • iOS13 适配问题 看这一篇就够了

    技术参考: apple login IOS13适配-详细 iOS 13 适配(持续更新中) iOS13适配 掘金 ...

  • iOS 13适配

    技术参考: apple login IOS13适配-详细 iOS 13 适配(持续更新中) iOS13适配 掘金 ...

  • 暗黑模式开发

    iOS13暗黑模式适配(项目开发版) iOS 13 DarkMode 暗黑模式 IOS 暗黑模式适配---基础适配

  • 自己适配iOS13解决的问题总结

    自己适配iOS13解决的问题总结 1.暗黑模式Dark Mode iOS 13 推出暗黑模式,UIView默认背景...

网友评论

      本文标题:iOS 13适配填坑总结

      本文链接:https://www.haomeiwen.com/subject/mcnfvctx.html