iOS13 DarkMode适配(一)
前言
笔者最近了解了DarkMode相关的颜色、图片、Web的适配,并且做了一个Demo QiDarkMode,给大家分享一下相关内容。
Dark Mode简介
在iOS 13.0及更高版本中,人们可以选择采用深色系统范围的外观,称为暗模式。Dark Mode(暗模式)是苹果在iOS13推出的新特性。使用iOS13及更高版本的系统的iOS 设备,可以使用暗模式,在暗模式下,系统会采用较暗的视图控件。开发者在开发过程中需要对视图控件进行相应暗模式的适配。
一、DarkMode Demo效果图
笔者分别做了Dark Mode Color、Image、Web的适配示例,分别录制了如下效果图。
QiDarkModeColor.gif QiDarkModeImage.gif QiDarkModeWeb.gif触发Dark Mode 方式
- iOS 触发DarkMode的方式除了上图中的方式还可以使用:设置 -> 显示与亮度 -> 切换深色外观 。
- 运行项目后,点击Xcode的
Environment Overrides
,选择Interface Style的 Light 或 Dark可以切换亮/暗模式。
- 运行项目后,点击Xcode的
- macOS触发Dark Mode,需要在在macOS10.14及更高版本的 Mojave系统中才支持,切换暗模式的方式为:系统偏好设置 -> 通用->外观 -> 浅色/深色
二、适配准备
1. @available(iOS 13.0, *)
首先我们在适配Dark Mode的时候,使用相关API需要先写明。
if (@available(iOS 13.0, *)) {
// Dark Mode适配相关代码
}
上述API写法较长,笔者写了如下一个宏,便于大家使用。使用方式为:QiAvailable(13.0)。
#define QiAvailable(version) @available(iOS version, *)
2. 找到需要背景色文字颜色
苹果官方为开发者提供了一些系统色,我们可以利用结合着文档提示及在Storyboard中测试,选择要填充的背景色。测试选择要使用的文字颜色。
QiDarkModeBackgroundColor.png QiDarkModeTextColor.png3. 开发过程中的None、Dark、Light、Any模式
开发过程中会需要设置图片或者颜色的Dark、Light、Any模式下的样式。
Xcode默认的图片和颜色的样式都为None,点击右侧属性中的Appearances可以切换样式为Any,Dark 或 Any,Light,Dark。
相关内容会在下文的中Color Asset部分有所体现。
三、Dark Mode Color
1. 系统色
一般我们可以在基类控制器中写明视图背景色,或基类视图中写明背景色。
如:
self.view.backgroundColor = [UIColor systemBackgroundColor];
textField.textColor = [UIColor placeholderTextColor];
label.backgroundColor = [UIColor tertiarySystemBackgroundColor];
2. 灵活设置颜色
如果我们需要灵活设置视图背景色或文字颜色,可以使用苹果提供的:
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
如:
if (QiAvailable(13.0)) {
self.view.backgroundColor = [UIColor systemBackgroundColor];
// 等价于
// 可以在Dark 和 Light 模式下设置所需的颜色 如Dark下某个接近黑色的颜色 Light下某个接近白色的颜色
self.view.backgroundColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) {
return [UIColor whiteColor];
} else if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [UIColor blackColor];
}
return [UIColor whiteColor];
}];
}
label.textColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [UIColor lightTextColor];
} else {
return [UIColor darkTextColor];
}
}];
3. Color Asset
添加Color Asset的方式如下图所示:
QiDarkModeColorAsset.png可以选择Color Asset 对应的Dark,Light,Any;及Dark,Any 模式下,要显示的颜色。
使用我们创建的Color Asset的方式为:
[UIColor colorNamed:@"StarColor"];
+ (**nullable** UIColor *)colorNamed:(NSString *)name API_AVAILABLE(ios(11.0));
这个API适用于iOS11及更高版本。
听同事CY说,这个API显示的颜色在iOS11.x的系统上会出现问题,但是苹果在Xcode11正式版已经解决了相关问题。
其中StartColor的配置如下:笔者这里的处理方式为:添加Color Asset,设置Appearance 为Any,Dark。表明笔者只关注Dark模式和非Dark模式,并且设置了非Dark模式显示为蓝色,Dark模式显示为紫色。
QiDarkModeImageColor.png四、Dark Mode Image
1. 设置Dark、Any模式下的图片
// Asset中设置多张图片
UIImage *logoImage = [UIImage imageNamed:@"QiShare"];
UIImageView *logoImageView = [[UIImageView alloc] initWithImage:logoImage];
logoImageView.frame = CGRectMake(120.0, 100.0, logoImage.size.width, logoImage.size.height);
[self.view addSubview:logoImageView];
设置多模式下图片的方式如下:选中图片-> 切换Appearance -> 把想要展示的图片拖入到对应模式下。
QiDarkModeImageAsset.png2. 监听Dark模式改变切换图片
如果我们的图片资源是加载的bundle中的图片。那么可以如下接口中监听模式变化,并且做相应的图片的更新的操作。
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_AVAILABLE(ios(8.0));
@property (nonatomic, strong) UIImageView *logoImageView;
@property (nonatomic, strong) UIImage *lightLogoImage;
@property (nonatomic, strong) UIImage *darkLogoImage;
self.darkLogoImage = [self qi_imageWithNamed:@"flutterLogo"];
self.lightLogoImage = [self qi_imageWithNamed:@"QiShare"];
UIImage *logoImg =self.lightLogoImage;
UIImageView *logoImgV = [[UIImageView alloc] initWithImage:logoImg];
self.logoImageView = logoImgV;
[self.view addSubview:logoImgV];
logoImgV.frame = CGRectMake(100.0, 100.0, logoImg.size.width, logoImg.size.height);
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
if (QiAvailable(13.0)) {
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.logoImageView.image =
self.darkLogoImage;
} else {
self.logoImageView.image =
self.lightLogoImage;
}
}
}
}
3. 改变图片tintColor
不同模式下控制图片显示相应tintColor。
// tintColor 改变Image着色
UIImage *starImage = [UIImage imageNamed:@"star"];
starImage = [starImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *starImageView = [[UIImageView alloc] initWithImage:starImage];
starImageView.frame = CGRectMake(100.0, 220.0, starImage.size.width, starImage.size.height);
starImageView.tintColor = [UIColor colorNamed:@"StarColor"];
[self.view addSubview:starImageView];
注意+ (**nullable** UIColor *)colorNamed:(NSString *)name API_AVAILABLE(ios(11.0));
这个API 是从iOS11.0开始支持的。
设置tintColor生效的一个注意点:
// UIImageRenderingModeAlwaysTemplate:Always draw the image as a template image, ignoring its color information
// 忽略图片的颜色信息 把图片作为模板图片来绘制
// 图片的显示颜色由tintColor控制
五、Dark Mode Web
在macOS10.14 Mojave系统中支持Dark Mode,切换暗模式和亮模式的方式为:系统偏好设置 -> 通用->外观 -> 浅色/深色。
下边的内容是笔者参考Dark Mode Support in WebKit:写的一个简单H5文件,大家有需要的话,可以提供给前端同学查看。相关内容,笔者也已经在Demo中使用本地加载的方式测试过,可以在不同模式下,正常切换。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Qi测试DarkMode</title>
<style>
:root {
color-scheme: light dark;
--special-text-color: black;
--bg-color: white;
}
@media (prefers-color-scheme: dark) {
:root {
--special-text-color: white;
--bg-color: black;
}
}
.special {
color: var(--special-text-color);
background-color: var(--bg-color);
}
body
{
background-color:var(--bg-color);
}
h1
{
color:var(--special-text-color);
text-align:center;
}
p
{
color:var(--special-text-color);
font-family:"Times New Roman";
font-size:20px;
}
</style>
</head>
<body>
<h1>测试DarkMode标题</h1>
<p>DarkMode段落。</p>
<picture>
<source srcset="http://img.zcool.cn/community/012b62554b2b0e000001bf72f9aad7.jpg@2o.jpg" media="(prefers-color-scheme: dark)">
<img src="http://p0.so.qhmsg.com/t0184f2659879a11464.jpg", width="300">
</picture>
</body>
</html>
六、Demo
详情见Demo:QiDarkMode
参考学习网址
- https://webkit.org/blog/8840/dark-mode-support-in-webkit/
- https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface?language=objc
- https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/dark-mode/
小编微信:可加并拉入《QiShare技术交流群》。
关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)
推荐文章:
2019苹果秋季新品发布会速览
申请苹果开发者账号的流程
Swift 5.1 (3) - 字符串
用Flutter 写一个简单页面
5分钟,带你迅速上手Markdown语法
Swift 5.1 (2) - 运算符
Swift 5.1(1) - 基础
Sign In With Apple(一)
奇舞周刊