0%

iOS13暗黑模式(Dark mode)适配

如何适配

暗黑模式的适配应该是iOS13适配工作中工作量最大的,下面看看App需要做什么改动才能支持dark mode。

颜色的适配

用户打开/管理暗黑模式后,APP无需重启即可自动切换

System color

官方推荐使用系统颜色进行适配,打开暗黑模式时会自动切换对应颜色,下面只是简单演示,系统提供的对应黑暗模式颜色还有很多,基本能满足各种需求,更详细的可以查看UIInterface.h这个头文件,会有更详细的说明

1
2
3
4
self.label.textColor = [UIColor labelColor];
self.secondLabel.textColor = [UIColor secondaryLabelColor];
self.thirdLabel.textColor = [UIColor tertiaryLabelColor];
self.fourthLabel.textColor = [UIColor quaternaryLabelColor];

1

Custom Color

如果实在不喜欢系统提供的颜色,苹果还提供了Custom Color的方式,到.xcassets下New一个Color Set后选上支持”Any, Dark”,而引用方式跟引用图片方式一致

1
self.customLabel.textColor = [UIColor colorNamed:@"Color"];

customcolor

图片的适配

图片的适配跟颜色类似,也提供了dark mode的模式,选上后把对应的暗黑模式图片拖放上去即可,引用方式不用改
image_dark_mode

适配方案

全局关闭

全局关闭dark mode,只需在Info.plist设置UIUserInterfaceStyle属性为Light即可。对于后续我们构建需要升级到Xcode11而又未适配好暗黑模式,只能暂时使用这种方案。

当然这是不建议的做法,虽然方便,但我个人认为苹果对实现了dark mode的APP会有加权

临时关闭

暗黑模式的适配工作是巨大的,也许没办法一步到位,这时候可以单独关闭未适配完的页面对暗黑模式的支持,以下是设置代码。

1
2
3
4
5
// Disable dark mode
self.view.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;

// Enable dark mode
self.view.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;

具体适配

颜色适配

所有的颜色统一通过VSStyle类来管理,App内取色只能通过VSStyle对应的方法获取,当前绝大部分代码是hard code了颜色值,改动的工作量是巨大的,但不得不做。

图片适配

本地图片参考如何适配中的图片的适配,准备相应的暗黑模式图片即可。而动态图片则参考UED建议使用遮罩处理(对于透明PNG的情况,感觉都不用处理,只需要把控件底色设置为白色即可),以下进行单独的技术调研说明
代码如下,会监听用户开启暗黑模式并进行遮罩,Demo new几百张图片并比较内存消耗,开启暗黑模式后,内存略微上涨0.1M

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//
// VSDarkModeImageView.m
// darkmode
//
// Created by heller on 2019/10/12.
// Copyright © 2019 heller. All rights reserved.
//
#import "VSDarkModeImageView.h"

@implementation VSDarkModeImageView

- (instancetype)initWithImage:(UIImage *)image {
if (nil != (self = [super initWithImage:image])) {
if (@available(iOS 13, *)) {
self.maskView = [self maskView];
}
}

return self;
}

/// 根据是否打开暗黑模式创建遮罩图片
- (UIView *)maskView {
UIView *maskView = nil;
if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
maskView = [UIView new];
maskView.backgroundColor = [UIColor blackColor];
maskView.alpha = 0.8f;
maskView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}

return maskView;
}

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
BOOL userInterfaceStyleChanged = [self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection];
if (userInterfaceStyleChanged) {
self.maskView = [self maskView];
}
}

@end

Demo
Demo
关闭暗黑模式
disable dark mode
开启暗黑模式
enable dark mode