美文网首页iOS 13适配
iOS13适配(踩坑)不完全汇总

iOS13适配(踩坑)不完全汇总

作者: _小沫 | 来源:发表于2019-10-13 23:41 被阅读0次
    1

    通过KVC获取/访问私有属性无效

    iOS13不允许通过valueForKey:valueForKeyPath:setValue: forKey: setValue: forKeyPath:获取或设置私有属性;以上KVC方法,使用Xcode11及之后版本编译会崩溃;Xcode10及之前版本虽不会崩溃,但无效;
    之前有使用私有属性的地方,均需另辟蹊径:

    • 设置UISearchBar的textField
      在13中把UISearchBar中的textField直接暴露给开发者使用,无需在通过KVC获取
    UITextField *searchTextField =  self.searchBar.searchTextField;
    
    • 修改UITextFiled的占位符字体大小以及颜色
      通过属性字符串来进行修改替代KVC方式:
    UITextField *textField = [[UITextField alloc] init];
    NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString: textField.placeholder attributes:@{NSForegroundColorAttributeName : [UIColor blackColor],NSFontAttributeName:[UIFont systemFontOfSize:16]}];
    textField.attributedPlaceholder = attributedStr;
    
    • 设置UISearchBar的cancelButton
      iOS13可以通过searcBar的层级遍历subviews获取到,但要注意的是iOS13 UISearchBar的层级有所不同,需要多遍历一层:
    for (UIView *v1 in [self.searchBar subviews]) {
        for (UIView *v2 in [v1 subviews]) {
            for (UIView *v3 in [v2 subviews]) {
                if([v3 isKindOfClass:[UIButton class]]){
                    UIButton *cancelButton = (UIButton *)v3;
                    ...
                }
            }
        }
    }
    
    • 设置状态栏背景颜色
      之前可以通过KVC获得状态栏,再设置其背景颜色;
    [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    

    iOS13中的解决方法是使用新APIUIStatusBarManager处理:

    UIStatusBarManager *statusBarManager = [UIApplication sharedApplication].keyWindow.windowScene.statusBarManager;
    if ([statusBarManager respondsToSelector:@selector(createLocalStatusBar)]) {
        UIView *localStatusBar = [statusBarManager performSelector:@selector(createLocalStatusBar)];
        if ([localStatusBar respondsToSelector:@selector(statusBar)]) {
            _statusBar = [localStatusBar performSelector:@selector(statusBar)];
        }
    }
    

    通过这种方式获得的状态栏,本质是新建了一个,修改此状态栏背景颜色不影响系统状态栏;所以要想状态栏显示我们想要的颜色,需要将这个创建的状态栏添加至UIWindow上,在界面销毁时再将其移出;

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        [[UIApplication sharedApplication].keyWindow addSubview:_statusBar];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [_statusBar removeFromSuperview];
        _statusBar = nil;
    }
    
    

    或者简单点可以直接新建一个和状态栏frame一样的view,添加到window上;

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        _customStatusBar = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame];
        [[UIApplication sharedApplication].keyWindow addSubview:_customStatusBar];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [_customStatusBar removeFromSuperview];
        _customStatusBar = nil;
    }
    

    UIStatusBarManager这种方式同样可以获取到状态栏网络状态;
    具体可以参考iOS13 获取StatusBar并且获取网络状态

    UISearchBar删除UISearchBarBackground崩溃

    去除UISearchBar背景色的代码

        for (UIView *view in self.searchBar.subviews.lastObject.subviews) {
            if ([view isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
                [view removeFromSuperview];
                break;
            }
        }
    

    以上代码在iOS13中,因为渲染问题而crash;解决方法是将[view removeFromSuperview];更改为view.layer.contents = nil;即可;

    模态弹出默认交互方式更改

    通过模态presentViewController跳转到另一个界面,iOS13之前modalPresentationStyle默认为UIModalPresentationFullScreen,而在iOS13默认为UIModalPresentationAutomatic;该方式present到UIAlertController等弹框界面效果和UIModalPresentationFullScreen一样;但present到一般vc时不会是全屏的,和之前相比差异明显;
    同样的,使用Xcode11及之后版本编译才会有这种差异;反之则不受影响;

    UITextView设置editable = NO的问题

    设置textView. editable = NO;代码后,iOS13中textView中的文字会显示不全;
    解决方法有:

    • 替换为:textView.userInteractionEnabled = NO;
    • 设置textView.textContainerInset = UIEdgeInsetsZero;

    MPMoviePlayerController不可使用

    使用Xcode11编译,使用MPMoviePlayerController的代码崩溃;报错:

    MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.

    UITableViewCell上的UILabel点击高亮显示问题

    UILabel设置背景颜色为和cell一样的颜色,点击cell高亮显示的时候,iOS13 cell背景颜色变灰色,但仍会看到label背景颜色,体验非常不好(之前版本系统是看不到label背景颜色的);解决方法是将label设置为透明;

    CNCopyCurrentNetworkInfo获取不到WiFi SSID

    iOS13增加了wifi信息的隐私保护,据说是为了防止开发人员通过WiFi SSID信息推断出用户的位置信息;所以在iOS13中如果用户没有开启定位权限,那么通过CNCopyCurrentNetworkInfo获取的SSID为空;也就是说SSID信息和定位绑定在一起了;
    解决方案:把获取SSID当成获取用户位置信息处理就行了;即在获取信息前申请用户定位权限授权,如果用户没有开启该权限根据自己的产品需求是否提示/引导用户开启;

    MJExtension字典转模型NSNull处理的不同

    将服务端数据字典转换为模型时,如果遇到服务端给的数据为NSNull时,iOS13,mj_JSONObject其中 class_copyPropertyList方法得到的属性里会多了一种EFSQLBinding类型,而且属性数量也不准确;这样会导致崩溃问题;不过MJExtension这个库也随即适配了iOS13,将该库升级到最新的即可;

    data类型的description方法返回的字符串不同

    iOS13调用description方法返回的字符串会多出length,bytes等字符串;类似:
    {length = 32, bytes = 0x778a7995 29f32fb6 74ba8167 b6bddb4e ... b4d6b95f 65ac4587 }
    如果之前获取推送的deviceToken字符串是通过description方法获取的,就会有问题了;解决方法:

        - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
        {
            if (![deviceToken isKindOfClass:[NSData class]]) return;
            const unsigned *tokenBytes = [deviceToken bytes];
            NSString *hexToken = [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])];
          ...
        }
    
    2019-10-21补充

    UIImageView设置圆角问题

    UIImageView设置圆角,且为设置背景颜色(或背景颜色设置为透明),个别图片圆角会有偏差;

    aa

    设置背景颜色即可解决问题;

    Dark Mode(深色模式)

    iOS13支持深色模式:UIKit提供新的系统颜色和 api 来适配不同颜色模式,xcassets 对素材适配也做了调整,具体适配可见: Implementing Dark Mode on iOS
    大部分APP暂时都没有计划适配Dark Mode,不适配Dark Mode的需要注意:

    • UIView未显示的设置背景颜色的(使用系统默认颜色),如果是Dark Mode,那么背景颜色会是黑色,会造成界面显示bug;
    • UITextField的文字Dark Mode模式下默认为白色,同样会有问题;
    • 其他类似的颜色问题;

    解决方法是:

    • 需要设置颜色的地方,都需显式的用代码设置(而不是采用系统默认的);但如果这种改动比较多的,工作量太大;
    • info.plist配置APP的显示模式为Light Mode,这样就算手机设置了Dark Mode对APP是不影响的;具体设置如下:
    dd

    获取不到用户通讯录备注信息

    iOS13中禁止开发者访问用户通讯录备注信息,所以在获取通讯录的keys中不能有下面的这个属性
    Contacts 的

    CNContactNoteKey 
    

    或者
    AddressBook的

    kABPersonNoteProperty
    

    以上汇总的是目前为止遇到的各种问题,欢迎各位补充

    相关文章

      网友评论

        本文标题:iOS13适配(踩坑)不完全汇总

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