iOS13适配-持续更新

1,292 阅读4分钟

1、iOS13DarkModel适配

禁用Dark Model

1.1、项目禁用DarkModel,在项目的info.plist中加入键值对:

  • Key-Value: User Interface Style Light

项目开始支持DarkModel

1.2、info.plist不做特殊配置,在项目里面Color方面的配置,目前iOS13中,在UIInterface.h中提供了一些动态色可供使用。如下所示:

可以通过UITraitCollection.currentTraitCollection.userInterfaceStyle来获取当前所处于的显示模式是Light或者Dark

2、UI方面

2.1、需要UI重新设计出图

增加图片,在Assets.xcassets,选中需更换的图片,这里需要使用dynamic Image,Appearances选择[Any,Dark]选项,Dark Appearance中加入适合新切图资源,然后切换Light、Dark的时候系统会自动读取图片

2.2、自定义动态UIColor

2.2.1、所以在项目中可以使用一些项目默认配色,这样就不用自定义颜色设置了,否则就需要自定义动态颜色。这里需要用到:
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvide
一个UIColor类方法,一个UIColor实例方法

UIColor类方法:

UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
        if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
            return [UIColor redColor];
        }
        else {
            return [UIColor greenColor];
        }
    }];
    
 [self.bgView setBackgroundColor:dyColor];
2.2.2、在不低于Xcode9+iOS11的开发环境中,可以使用Assets.xcassets,自定义New Color Set,Appearances选择[Any,Dark]选项,自定义这个color set名称,然后通过Input Method来选择色值,这种颜色值方法只适用于iOS11及以上:
@interface UIColor (UIColorNamedColors)
+ (nullable UIColor *)colorNamed:(NSString *)name API_AVAILABLE(ios(11.0));      // load from main bundle
+ (nullable UIColor *)colorNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection API_AVAILABLE(ios(11.0));
@end

3、监听Light和Model的切换

2.1、监听系统模式变化

// 注意:参数为变化前的traitCollection
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;
// 判断两个UITraitCollection对象是否不同
-(BOOL)hasDifferentColorAppearanceComparedToTraitCollection:(UITraitCollection *)traitCollection;

4、自定义动态CGColor

4.1、适配CGColor

通过UIcolor的实例方法resolvedColorWithTraitCollection

// 通过当前traitCollection得到对应UIColor,然后将返回的UIColor转为CGColor

  • 方法一
-(UIColor *)resolvedColorWithTraitCollection:(UITraitCollection*)traitCollection;
UIColor *instanceColor = [otherInstanceColor resolvedColorWithTraitCollection:traitCollection];
self.view.layer.backgroundColor = instanceColor.CGColor
  • 方法二
// 使用当前trainCollection调用此方法
- (void)performAsCurrentTraitCollection:(void (^)(void))actions;

 [self.traitCollection performAsCurrentTraitCollection:^{
        self.view.layer.backgroundColor = otherInstanceColor.CGColor;
    }];
  • 方法三
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
        if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
            return [UIColor blueColor];
        }
        else {
            return [UIColor greenColor];
        }
    }];
        layer.backgroundColor = dyColor.CGColor;
}
我个人觉得目前上述方法一、方法二两个方法没有多大的意义,毕竟可以直接通过UIColor的CGColor方法直接转换,如果各位有什么有其他理解,请帮忙斧正,谢谢。

5、富文本NSAttributedString的适配

iOS的富文本需要注意Light和Dark的模式变化

6、Status Bar变化

Status Bar变化,iOS13以后,增加了一种UIStatusBarStyle枚举类型,分别是:

UIStatusBarStyleDefault         //自动选择黑色或白色
UIStatusBarStyleDarkContent     //文字黑色
UIStatusBarStyleLightContent    //文字白色

7、UIActivityIndicatorView的样式

在头文件中发现iOS13的UIActivityIndicatorView的头文件中Style已经对原有样式做了标记:

typedef NS_ENUM(NSInteger, UIActivityIndicatorViewStyle) {
    UIActivityIndicatorViewStyleMedium  API_AVAILABLE(ios(13.0), tvos(13.0)) = 100,
    UIActivityIndicatorViewStyleLarge   API_AVAILABLE(ios(13.0), tvos(13.0)) = 101,
    
    UIActivityIndicatorViewStyleWhiteLarge API_DEPRECATED_WITH_REPLACEMENT("UIActivityIndicatorViewStyleLarge", ios(2.0, 13.0), tvos(9.0, 13.0)) = 0,
    UIActivityIndicatorViewStyleWhite API_DEPRECATED_WITH_REPLACEMENT("UIActivityIndicatorViewStyleMedium", ios(2.0, 13.0), tvos(9.0, 13.0)) = 1,
    UIActivityIndicatorViewStyleGray API_DEPRECATED_WITH_REPLACEMENT("UIActivityIndicatorViewStyleMedium", ios(2.0, 13.0)) API_UNAVAILABLE(tvos) = 2,
};
  • 下面3个枚举类型已经失效,新增加了上面2个,上面两个枚举类型可以自适应系统显示模式的切换

8、Sign in with Apple

iOS的App如果提供了第三方登录,那就必须要提供Sign in with Apple选项,否则审核方面会有问题,有关于此的官方链接:

9、KVC限制

iOS13以后通过KVC来获取系统的私有属性,很容易崩溃,只能通过其他的属性字符串来处理,特别是UITextField,UISearchBar。

9.1、UITextField不可以在通过KVC来获取其私有属性,例如placeholderLabel的text、color等
9.2、UISearchBar的searchField属性,但是iOS13提供了一个新的searchTextField属性

10、iOS13以后present的model弹出样式改变了

iOS13的ViewController的弹出效果,默认有视差效果,如果需要全屏,需要设置ViewController的modalPresentationStyle属性,设置为UIModalPresentationFullScreen

11、UISegmentedControl默认样式修改

  • 默认样式变为白底黑字,如果设置设置过颜色的话,则页面需要做适配

12、增加蓝牙权限的使用目的描述

  • CBCentralManager,iOS13以前,可以直接使用蓝牙,不会出现权限提示,iOS13后,再使用就会提示了。在info.plist里需要增加NSBluetoothAlwaysUsageDescription

13、UITabbar层次改变

  • 这个需要自己多摸索了,涉及到shadowImage去线,TabBar的红点提示位置

14、标记为 API_DEPRECATED 部分类被移除

  • MPMoviePlayerController ==> AVPlayerViewController
  • UISearchDisplayController ==> UISearchController 可能还有其他的,有遇到的可以说一下,我更新一下

15、LaunchImage、UIWebview即将消失

  • 从2020年4月开始,所有使⽤iOS13的SDK的App将必须提供LaunchScreen,LaunchImage即将退出历史舞台。可以使用Launch Storyboards来进行解决。
  • UIWebview也需要逐渐使用WKWebview替换掉

16、CNCopyCurrentNetworkInfo的变化

  • iOS13 以后只有开启了 Access WiFi Information capability,才能获取到 SSID 和 BSSID

17、DeviceToken变化

  • [deviceToken description] 会受不同运行环境及系统的影响而发生变化,iOS13下需要对NSData做一下HexString转换,iOS13一下保持原样,转换:
// iOS13适配
- (NSString *)getHexStringForData:(NSData *)data {
    NSUInteger len = [data length];
    char *chars = (char *)[data bytes];
    NSMutableString *hexString = [[NSMutableString alloc] init];
    for (NSUInteger i = 0; i < len; i++) {
        [hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]];
    }
    return hexString;
}