iOS13 适配

1、必须使用 WKWebView 代替 UIWebView

2、直接在 Info.plist 中添加一栏:User Interface Style : Light,即可在应用内禁用暗黑模式。

3、应用使用了第三方或社交账号登录服务就必须支持Sign In with Apple

4、不允许使用 valueForKeysetValue:forKey: 来获取或者设置私有属性

// 崩溃 api
UITextField *textField = [searchBar valueForKey:@"_searchField"];

// 替代方案 1,使用 iOS 13 的新属性 searchTextField
searchBar.searchTextField.placeholder = @"search";

// 替代方案 2,遍历获取指定类型的属性
- (UIView *)findViewWithClassName:(NSString *)className inView:(UIView *)view{
    Class specificView = NSClassFromString(className);
    if ([view isKindOfClass:specificView]) {
        return view;
    }

    if (view.subviews.count > 0) {
        for (UIView *subView in view.subviews) {
            UIView *targetView = [self findViewWithClassName:className inView:subView];
            if (targetView != nil) {
                return targetView;
            }
        }
    }
    
    return nil;
}

// 调用方法
 UITextField *textField = [self findViewWithClassName:@"UITextField" inView:_searchBar];

// 崩溃 api
[searchBar setValue:@"取消" forKey:@"_cancelButtonText"];

// 替代方案,用同上的方法找到子类中 UIButton 类型的属性,然后设置其标题
UIButton *cancelButton = [self findViewWithClassName:NSStringFromClass([UIButton class]) inView:searchBar];
[cancelButton setTitle:@"取消" forState:UIControlStateNormal];

// 崩溃 api。获取 _placeholderLabel 不会崩溃,但是获取 _placeholderLabel 里的属性就会
[textField setValue:[UIColor blueColor] forKeyPath:@"_placeholderLabel.textColor"];
[textField setValue:[UIFont systemFontOfSize:20] forKeyPath:@"_placeholderLabel.font"];

// 替代方案 1,去掉下划线,访问 placeholderLabel
[textField setValue:[UIColor blueColor] forKeyPath:@"placeholderLabel.textColor"];
[textField setValue:[UIFont systemFontOfSize:20] forKeyPath:@"placeholderLabel.font"];

// 替代方案 2
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"输入" attributes:@{
    NSForegroundColorAttributeName: [UIColor blueColor],
    NSFontAttributeName: [UIFont systemFontOfSize:20]
}];

4、推送的 deviceToken 获取到的格式发生变化,使用下面方法进行处理

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    if (![deviceToken isKindOfClass:[NSData class]]) {
        return;
    }
    const unsigned char *tokenBytes = deviceToken.bytes; 
    NSInteger count = deviceToken.length;
    
    // 数据格式处理
    NSMutableString *hexToken = [NSMutableString string];
    for (int i = 0; i < count; ++i) {
        [hexToken appendFormat:@"%02x", tokenBytes[i]];
    }
    NSLog(@"deviceToken:%@", hexToken);
}

5、使用 presentViewController 方式打开模态视图默认了新加的一个枚举值 UIModalPresentationAutomatic,使用全屏显示,需要按如下处理:

- (UIModalPresentationStyle)modalPresentationStyle {
    return UIModalPresentationFullScreen;
} 

6、UISearchBar 黑线处理会导致崩溃,现在需要设置背景为空

[_searchBar setBackgroundImage:[UIImage new]];