暗黑模式适配 | iOS

  • 暗黑模式的适配,以及可能碰到的问题

![图片](/assets/blogImg/darkmodel2.jpeg)

前言

  • iOS13苹果推出了暗黑模式,通俗点讲就是黑色主题,
  • 苹果在推出暗黑模式的时候是抱着这么几个初衷的
    1. 省电,黑色的主题可以在一定程度上降低屏幕的用电量
    2. 降低刘海屏的存在感,国产Android手机在不断的尝试屏幕的方式,包括挖孔屏、伪全面屏等等;苹果因为摄像头等原因,无法改变屏幕布局,暗黑模式能在一定程度上降低用户对于刘海屏的抵触感,换句话讲就是降低刘海屏的存在感
    3. 护眼等

适配

注意点:图片和文字颜色都有需要注意的地方,下文中会对应提到
UIColor 内置用来获取区分模式的颜色:[UIColor colorWithDynamicProvider:…];

  • iPhone暗黑模式的切换在 ‘ 设置 ‘ -> ‘ 显示与亮度 ‘
  • 适配主要分几点:1. 图片,2. 颜色,3. 切换

一、图片

  • 1.Xcode的资源图片内带有 Appearances 选项,如果所示 ‘None’ 为默认,切换到需要的模式
  • 2.讲对应切图填充即可,系统会在用户切换暗黑模式的时候自动修改
![图片](/assets/blogImg/darkmode1.png)
  • 3.图片的适配存在一个问题,Tabbar的图片并不会随着系统模式的切换而切换
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma mark - 解决 tabbar 暗黑模式 图片不切换问题
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
[super traitCollectionDidChange:previousTraitCollection];
if (@available(iOS 13.0, *)) {
// Tabbar不支持根据暗黑模式自动修改,这里重新设置下达到自动修改目的
//[newImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
for (int i = 0; i < 5; i++){
UIViewController *vc = self.childViewControllers[i];
UIImage *newImage = [[UIImage imageNamed:self.normalImageArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
vc.tabBarItem.image = [newImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
}
}

二、文本

文本注意点
  • 这里主要提供一些思路,具体执行还是看小伙伴你们自己的实现方式
  • iOS内置了适配的颜色,例如:UIColor.lightGrayColor,能用系统颜色的尽量在开发过程中
  • 开发过程中写一套自己的基类,在适配的过程中能极大的减少代码量
  • 系统在切换的时候会通知所有的window、view需要更新样式,通知到对应函数,比如UIView的:layoutSubviews,UIContrroller的viewWillLayoutSubviews,这里比较推荐的是traitCollectionDidChange(),无论是view或者是controller都会调用
文本的适配
  • 1.基本的适配方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
UIColor *titleColor;
if (@available(iOS 13.0, *))
{
[UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection){
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark){
titleColor = UIColor.blackColor;
} else {
titleColor = UIColor.whiteColor;
}
}];
} else {
titleColor = UIColor.whiteColor;
}
self.titleLab.textColor = titleColor;
  • 2.改良版
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
// 给UIColor添加Category
// self.titleLab.textColor = [UIColor getYTDynamicBackGroundColor];

/** .h 文件 */
@interface UIColor (YTDynamicColor)

+ (UIColor *)getYTDynamicBackGroundColor;

@end

/** .m 文件 */
#import "UIColor+YTDynamicColor.h"

@implementation UIColor (YTDynamicColor)

/*
* 获取动态的背景颜色,暗黑模式下,背景黑色
*/

+ (UIColor *)getYTDynamicBackGroundColor{
return [self getColorWithDark:UIColor.blackColor LightColor:UIColor.whiteColor];
}

/*
* 给暗黑以及浅色两种模式的颜色,匹配返回
*/
+ (UIColor *)getColorWithDark:(UIColor *)dark LightColor:(UIColor *)light{
if (@available(iOS 13.0, *))
{
return [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection){
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark){
return dark;
} else {
return light;
}
}];
} else {
return light;
}
}

@end

  • 3.进阶版
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
44
45
46
47
48
49
50
51
52
53
54
55
56
// 给UIColor添加Category,配合关联
// 如下关联对象还有点粗糙,相信明白的小伙伴知道如何改了

// self.titleLab.textColor = [UIColor YTDynamicBackGroundColor];

/** .h 文件 */
@interface UIColor (YTDynamicColor)

+ (UIColor *)YTDynamicBackGroundColor;

@end


/** .m 文件 */
#import "UIColor+YTDynamicColor.h"

@implementation UIColor (YTDynamicColor)

/*
* 获取动态的背景颜色,暗黑模式下,背景黑色
*/
static const char YTDynamicBackGorundKEY = '\0';

+ (UIColor *)YTDynamicBackGorundColor{

UIColor *color = objc_getAssociatedObject(self, &YTDynamicBackGorundKEY);
if (!color) {
color = [self getColorWithDark:UIColor.blackColor LightColor:UIColor.whiteColor];
objc_setAssociatedObject(self, &YTDynamicBackGorundKEY,
color, OBJC_ASSOCIATION_RETAIN);
}
return color;
// 被废弃的方式
// return [self getColorWithDark:UIColor.blackColor LightColor:UIColor.whiteColor];
}

/*
* 给暗黑以及浅色两种模式的颜色,匹配返回
*/
+ (UIColor *)getColorWithDark:(UIColor *)dark LightColor:(UIColor *)light{
if (@available(iOS 13.0, *))
{
return [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection){
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark){
return dark;
} else {
return light;
}
}];
} else {
return light;
}
}

@end

  • 注意点:如果文字颜色使用的CGColor,也不会自动切换,也可以使用上面TTabbar的处理方式
1
2
3
4
5
6
7
8
#pragma mark - 解决 tabbar 暗黑模式 图片不切换问题
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
[super traitCollectionDidChange:previousTraitCollection];
self.AAA.layer.***Colorr = self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? [UIColor blackColor].CGColor : [UIColor whiteColor].CGColor;
// if (@available(iOS 13.0, *)) {
// }else{
// }
}