本文转载自iOS 13适配——暗黑模式 – 番薯大佬,有改动

iOS13有什么亮点?

iOS 13.0正式版发布以来,最大的亮点还是新增的支持Dark Mode(暗黑模式)。

App 要做暗黑的适配吗?

首先,目前iPhone自带软件基本上适配了暗黑模式,开启暗黑模式后,打开软件都是黑底白字。 其次,对于开发者而言,苹果也提供了相应的 API 接口,以供开发者使用。 最后,貌似没有强制要求,建议开发者根据自己的APP 类型来选择是否兼容暗黑模式。

如果自己的 App不想适配暗黑模式,要怎么做?

如果要使app一直保持黑色或者白色模式,可以在info.plist文件里面设置属性User Interface Style值为Light或者Dark设置info.plist

注意:属性值LightDark需要首字母大写,否则无效。

App暗黑模式的适配怎么做?

适配包含两方面,颜色适配和图片适配。

颜色适配要怎么做?

方法1 使用系统颜色systemBackgroundColor,浅色模式下显示白色,深色模式下显示黑色;存在问题,只能显示白色或黑色。

self.view.backgroundColor = UIColor.systemBackgroundColor;

或使用系统颜色labelColor,浅色模式下显示黑色,深色模式下显示白色; 存在问题,只能显示黑色或白色。

label.textColor = UIColor.labelColor;

常用的系统动态模式颜色:文本颜色labelColor、辅助内容的文本标签颜色secondaryLabelColor、三级tertiaryLabelColor、超链接标签颜色linkColor、分隔符(细边框或者分割线)separatorColoropaqueseparatorColor、界面背景色systembackgroundColor等。

方法2 根据模式,实时显示自定义颜色。 iOS13系统已经提供了相应的 API用于处理颜色,如下所示:

+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider;
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider;
// 设置自定义颜色
UIColor *textColor = UIColor.greenColor;
if (@available(iOS 13.0, *)) {
	textColor = [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
		if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
			return UIColor.orangeColor;
		}
		return UIColor.greenColor;
	}];
}
// 显示自定义颜色
label.textColor = textColor;

方法3 根据模式,实时监听修改颜色

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
  [super traitCollectionDidChange:previousTraitCollection];
  
  if (@available(iOS 13.0, *)) {
    if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
      
      if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
        // iOS13 暗黑模式
        self.view.layer.backgroundColor = UIColor.redColor.CGColor;
      } else {
        // iOS13 普通模式
        self.view.layer.backgroundColor = UIColor.yellowColor.CGColor;
      }
    }
  }
  
}

除了代码实现,其他方式实现颜色的暗黑适配

前面3种方法都是直接通过代码来实现,还有第4种方法是通过在Assets.xcassets里定义颜色来实现。 方法4 步骤1:选择Assets.xcassets,显示后鼠标点击右键出现菜单,选择New Color Set 步骤2:创建后,选中并重命名,如textColor,后进行操作显示Appearances,选择属性Any, Dark,最后分别设置两种颜色 步骤3:通过函数+ (nullable UIColor *)colorNamed:(NSString *)name获取颜色,并进行赋值使用

label.textColor = [UIColor colorNamed:@"textColor"];

设置如图示设置颜色 Apperances设置方法:选中该资源文件, 打开 Xcode ->View ->Inspectors ->Show Attributes Inspectors (或者Option+Command+4)视图,将 Apperances 选项 改为Any,Dark

我的 App 适配了暗黑模式,但是我想App 里的有些界面不要暗黑模式的适配,有什么办法吗?

若想要某个UI 保持白色模式,或黑色模式,可以设置属性overrideUserInterfaceStyle的值为UIUserInterfaceStyleLight或值为UIUserInterfaceStyleDark

前面告诉了我颜色的暗黑模式适配,那图片适配的暗黑模式适配又是怎么实现的?

方法1 通过代码实现

注意:图标资源可以保存在Assets.xcassets,也可以直接在项目中创建资源目录保存。

// 定义不同模式的图标
UIImage *image = [UIImage imageNamed:@"lightName"];
if (@available(iOS 13.0, *)) {
	UIImage *imgs = [UIImage imageNamed:@"lightName" inBundle:nil compatibleWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
	[imgs.imageAsset registerImage:[UIImage imageNamed:@"darkName"] withTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]];
	image = [imgs.imageAsset imageWithTraitCollection:UITraitCollection.currentTraitCollection];
}
// 获取并使用图标

方法2 通过设置Assets.xcassets实现 注意:该方法时,图标资源必须保存在Assets.xcassets。 步骤1 设置图标,并重命名为icon,如图示图片

步骤2 使用

imageView.image = [UIImage imageNamed:@"icon"];

图片在暗黑模式下的适配的总结

既是总结,也是强调,在暗黑模式的适配过程中的注意事项: 1、layer颜色的适配,只能使用回调方法- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection监听处理; 2、可以在Info.plist添加属性User Interface Style并设值为LightDark,使 app 保持白色模式,或黑色模式; 3、可以使用设置属性overrideUserInterfaceStyle值为UIUserInterfaceStyleLightUIUserInterfaceStyleDark,使某个 UI 保持为白色模式,或黑色模式;

另外,补充下开发中可以通过调用UITraitCollection.currentTraitCollection.userInterfaceStyle获取当前模式,以便可以根据不同的模式执行不同的操作。 如:

if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
 	NSLog(@"DarkMode");
} else {
 	NSLog(@"LightMode");
}

REFERENCE