苹果在iOS13中为iPhone引入了深色模式,所有 UIKit 本身所提供的 UI 控件(例如 UIView,UILabel,UITextView等等) ,只要没有针对颜色等内容特殊设置过,都会自动适配深色模式,这部分是我们开发者不需要去关心的,我们只需要关心怎么判断系统的当前模式和对自定义视图的内容适配黑暗模式。
模式判断
UIView 、UIViewController 、UIScreen、UIWindow 这些类都拥有一个叫做 traitCollection 的属性,traitCollection里面有一个userInterfaceStyle属性,而颜色模式就是存在 userInterfaceStyle 中。
if (@available(iOS 13.0, *)) {
UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle;
if (mode == UIUserInterfaceStyleDark) {
NSLog(@"深色模式");
} else if (mode == UIUserInterfaceStyleLight) {
NSLog(@"浅色模式");
} else {
NSLog(@"未知模式");
}
}
// 各种枚举值
typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
UIUserInterfaceStyleUnspecified,
UIUserInterfaceStyleLight, 浅色模式
UIUserInterfaceStyleDark, 深色模式
} API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);
模式变化的监听
在UITraitEnvironment协议中, 为我们提供了一个监听当前模式变化的方法。
@protocol UITraitEnvironment <NSObject>
// 当前模式
@property (nonatomic, readonly) UITraitCollection *traitCollection API_AVAILABLE(ios(8.0));
// 重写该方法监听模式的改变
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_AVAILABLE(ios(8.0));
@end
颜色适配
在iOS13以后,UIKit给我们提供了很多的动态颜色,以system开头的都是动态颜色,当我们给 UI 控件设置了动态颜色以后UI 控件就会自动的根据当前是否是黑暗模式展现出来对应的颜色。
self.view.backgroundColor = [UIColor systemRedColor];
但是系统提供的这些动态颜色肯定是无法满足我们的实际开发需求,在 iOS 13 中, UIKit 为 UIColor 所提供的 新 API 来创建我们自己的动态颜色。
UIColor *color = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
//深色模式下的颜色
return [UIColor blueColor];
}else {
//浅色模式下的颜色
return [UIColor purpleColor];
}
}];
self.view.backgroundColor = color;
当然我们还可以在xcassets进行设置颜色适配,在xcode11之后才有的功能。
点击Color set,出现下面界面
self.view.backgroundColor = [UIColor colorNamed:@"testColor"];
图片设置
普通模式和深色模式下展示不同的照片,可以利用xcassets 中图片新增的 Apperance 属性,分别设置两种模式下所使用到的图片。