本来几个月前就应该更新这篇iOS 13的DarkMode文章的…然而发现放到了某个未命名的.md文件里头去了…哈哈,整理一下重新发一下
首先,我看到好多朋友在群里问,为什么用新编译器(Xcode 11)后开了darkmode之后开启darkmode.[UIColor whiteColor]这种设置颜色之后会变成黑的.这是因为iOS 13(Xcode 11及以上)的UIColor变成了dynamic的.
不适配黑暗模式解决方法
- 1.使用低于Xcode 11的Xcode版本.
- 2.不要使用"动态"的颜色.推荐使用手动创建的rgb色.
- 3.在info.plist中添加key:
UIUserInterfaceStyle
.value为String类型的Light
- 4.在UIViewController中设置
self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight
.记得判断一下版本.
适配黑暗模式的情况
首先,我们看下和darkmode有关的枚举
UIUserInterfaceStyle
typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
/// 未确认
UIUserInterfaceStyleUnspecified,
/// 亮色模式
UIUserInterfaceStyleLight,
/// 黑暗模式
UIUserInterfaceStyleDark,
} API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);
注意的是iOS 13以上,所有系统提供的color都变成了dynamiccolor.也就是说,.light的情况下和.dark的情况下的表现的颜色是不一样的.然而,cgcolor还是非动态的.
UIColor的适配
代码方式
UIColor *dynamicColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
switch (traitCollection.userInterfaceStyle) {
case UIUserInterfaceStyleLight: {/// 亮色模式颜色
return [UIColor whiteColor];
}
break;
case UIUserInterfaceStyleDark: {/// 暗色模式颜色
return [UIColor whiteColor];
}
break;
default: {
return [UIColor whiteColor];
}
break;
}
}];
注意的是.如果颜色没有被使用.这个block就不会有回调.
Asset.xcassets方式
创建Color Set
使用也比较简单
[UIColor colorNamed:@"assetname"];
UIImage的适配
UIImage *image = [UIImage new];
[image.imageAsset registerImage:[UIImage imageNamed:@"1"] withConfiguration:[[UIImageConfiguration alloc] configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]];
[image.imageAsset registerImage:[UIImage imageNamed:@"2"] withConfiguration:[[UIImageConfiguration alloc] configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]];
self.imageView.image = image;
Asset.xcassets方式
DarkMode的补充说明
UITraitCollection直接翻译就是UI有关的特性集合.像是Darkmode切换、当前设备是哪个os的之类的.我们就是需要其中的userInterfaceStyle
属性.
直接获取当前的userInterfaceStyle
UITraitCollection *traitCollection = [UITraitCollection currentTraitCollection];
switch (traitCollection.userInterfaceStyle) {
case UIUserInterfaceStyleUnspecified:
break;
case UIUserInterfaceStyleLight:
break;
case UIUserInterfaceStyleDark:
break;
default:
break;
}
通过UIView与UIViewController获取改变后的状态
/// 因为UIView以及UIViewController都实现了如下的代理,可以通过如下代理获取UITraitCollection的改变后的状态.
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
补充
强制设置某个View或者VC的显示模式
self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
强制设置所有View、VC的显示模式
ps:设置window的rootVC也是和上面的设置一样只会影响当前VC.modal出来其他的还是不会改变.如果设置window的属性的话.就会改变所有的了
((SceneDelegate *)[UIApplication sharedApplication].connectedScenes.anyObject.delegate).window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
或是把info.plist中的UIApplicationSceneManifest
删掉.使用下面的"老代码".
[UIApplication sharedApplication].delegate.window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;