iOS 13终于引来了暗黑模式。

每当新特性的到来,iOS开发者们既紧张又有点小兴奋,怀揣着被虐的心态,让我们来看看暗黑模式到底是个啥。

虽然这是一个设计驱动的需求,但是本着一颗虔诚(暴躁)的心,我们还是要一步步来,“工欲善其事、必先利其器”,搞清楚应该怎么做。

下载 Xcode11,跑起来你的项目。模拟器启动后,在“设置”-“开发者”中打开“Dark Appearance”后,你的项目就自动运行在暗黑模式了。

有些界面会很奇怪,这很正常,可以从一个界面入手,一步步优化它。

UITraitCollection

先来了解下 UITraitCollection。

在 iOS 13 中,我们可以通过 UITraitCollection 来判断当前系统的模式。UIView 和 UIViewController 、UIScreen、UIWindow 都已经遵从了UITraitEnvironment 这个协议,因此这些类都拥有一个叫做 traitCollection 的属性,在这些类中,我们可以这样去判断当前 App 的颜色模式:

BOOL isDark = (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark);

另外,我们还可以通过 UITraitCollection.current 这个属性来获取当前 App 的颜色模式。但是并不是所有的时候获取的都是正确的,只有在下面这些方法中,才可以放心的使用这个属性:

UIView

UIViewController

UIPresentationController

draw()

layoutSubview()

viewWillLayoutSubviews() viewDidLayoutSubviews()

containerViewWillLayoutSubviews() containerViewDidLayoutSubviews()

traitCollectionDidChange() tintColorDidChange()

traitCollectionDidChange()

traitCollectionDidChange()

还没适配完又不想给用户看,可以先暂时全局关闭暗黑模式:

在 Info.plist 文件中,添加 key 为 User Interface Style,类型为 String,value 设置为 Light 即可。

infoplist.png

在 iOS 13中,UIView、UIViewController 、UIWindow 有了一个 overrideUserInterfaceStyle 的新属性,可以覆盖系统的模式。

单个页面或视图关闭暗黑模式,设置 overrideUserInterfaceStyle 为对应的模式,强制限制该视图与其子视图以设置的模式进行展示,不跟随系统模式改变进行改变。

self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;

设置此属性会影响当前view/viewController/window 以及它下面的任何内容。

如果你希望一个子视图监听系统的模式,请将 overrideUserInterfaceStyle 属性设置为.unspecified。

颜色

系统颜色

在 iOS 13中,苹果引入了全新系统颜色,系统颜色是动态的,会根据当前系统是默认模式还是暗黑模式动态调整颜色。

苹果还提供了一组动态的灰度颜色。

systemcolor.png

语义化颜色

苹果提供了一套根据颜色使用目的而约定颜色命名的语义化颜色。语义化颜色也是动态颜色。

例如系统背景色(SystemBackground)、分割线颜色(SeparatorColor)等等,使用语义化颜色确保你的 App 具有和系统应用高度类似的配色风格。通过使用语义化颜色,可以让你的 App 更加贴近原生体验,这是官方希望达到的最佳体验。

elementcolor.png

以上两种动态颜色,是 iOS 13 才支持的新特性,并且颜色有限,大概率不能满足 App 的使用,继续往下看。

自定义颜色:通过 Assets 配置

在 iOS 11和 Xcode 9 中,我们可以在 Images.xcassets 中添加颜色。

现在我们可以为颜色再配置一个用于暗黑模式的对应的颜色。

assets.png

通过代码自定义颜色

+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider;

- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider;

iOS 13 提供了的新方法,可以在 block 中判断 traitCollection.userInterfaceStyle,根据系统模式设置返回的颜色。

+(UIColor *)generateDynamicColor:(UIColor *)lightColor darkColor:(UIColor *)darkColor{

if (@available(iOS 13.0, *)) {

UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {

if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) {

return lightColor;

}else {

return darkColor;

}

}];

return dyColor;

}else{

return lightColor;

}

}

图片

SF Symbols

苹果在 WWDC19 上引入了 SF Symbols 。SF Symbols是一个巨大的矢量图标库(超过1500),可供开发人员在自己的 App 中使用。

更多可以查看关于 SF Symbols 的 Session 206-Introducing SF Symbols,下载.dmg可以查看全部图标。苹果在自己的应用中使用,也推荐开发者使用。

if (@available(iOS 13.0, *)) {

_iconIV.image = [UIImage systemImageNamed:@"plus.circle"];

}

不想用 SF Symbols 的话,还有一种方式就是和自定义颜色相同的方法,在 Images.xcassets 中配置不同模式下的图片。

assets_image.png

在 Images.xcassets 中设置颜色和图片是向下兼容的,iOS 13 以下的系统会默认取Any状态下的设定,iOS 13 会根据系统模式取Any或Dark下的设定。

模糊效果

在 iOS 中,我们创建模糊效果的 UIVisualEffectView 的代码也会有明确表面明暗的情况。

在 iOS 13 中,我们需要让这些模糊效果随着系统模式的切换而切换。UIKit 提供了新的模糊样式且是动态的,会随着系统模式的改版而自动匹配。

利用 UIVisualEffectView 来创建一些类似模糊的效果时,不要设置类似 UIBlurEffectStyleExtraLight 这样带有明确颜色的效果,而是设置 UIKit 中新提供的动态样式的效果,比如 UIBlurEffectStyleSystemThinMaterialLight 或 UIBlurEffectStyleSystemThinMaterialDark。

UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemMaterial];

UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];

启动图

如果我们的 App 使用了 LaunchImage 作为启动屏,那么就应该考虑把 LaunchImage 换成 LaunchScreen.storyboard 了,因为在 Xcode 11 中 LaunchImage 并不能像普通的图片那样针对深色模式设置另外的一张图片。

富文本

给 Attributed String 加上一个 foregroundColor 属性,设置动态的颜色即可。

[attr addAttribute:NSForegroundColorAttributeName value:[UIColor labelColor] range:NSMakeRange(10, 20)];

layer

关于 layer 的话,可以通过调用 view. traitcollection 从 view 中获得当前的 UITraitCollection。

UIColor *resolvedColor = [[UIColor labelColor] resolvedColorWithTraitCollection:self.view.traitCollection];

label.layer.borderColor = resolvedColor.CGColor;

如果我们需要解析多种颜色,UITraitCollection 有一个方便的 performAsCurrent() 方法:

[self.view.traitCollection performAsCurrentTraitCollection:^{

for (UIColor *color in self.colorsArr) {

// 批量拿到 color.CGColor

}

}];

调试 dark mode

storyboards 和 xib 文件,现在可以切换界面之间的样式是默认还是暗黑了。

在模拟器上,也可以直接切换暗黑模式进行调试了。

debug.JPG

一些新变更

UIActivityIndicatorView 的 style 变更了。

iOS 13前 的 UIActivityIndicatorViewStyle:

typedef NS_ENUM(NSInteger, UIActivityIndicatorViewStyle) {

UIActivityIndicatorViewStyleWhiteLarge,

UIActivityIndicatorViewStyleWhite,

UIActivityIndicatorViewStyleGray,

};

iOS 13后,由于暗黑模式,上述三个属性都被废弃,建议使用如下 style:

typedef NS_ENUM(NSInteger, UIActivityIndicatorViewStyle) {

UIActivityIndicatorViewStyleMedium,

UIActivityIndicatorViewStyleLarge,

UIActivityIndicatorViewStyleWhiteLarge API_DEPRECATED_WITH_REPLACEMENT("UIActivityIndicatorViewStyleLarge",

UIActivityIndicatorViewStyleWhite API_DEPRECATED_WITH_REPLACEMENT("UIActivityIndicatorViewStyleMedium",

UIActivityIndicatorViewStyleGray API_DEPRECATED_WITH_REPLACEMENT("UIActivityIndicatorViewStyleMedium",

};

Status Bar 的 style 变更了。

在 iOS 13 之前,状态栏的样式的枚举值也带有着明显的颜色倾向,UIStatusBarStyleDefault、UIStatusBarStyleLightContent。

现在,状态栏的 default 样式会根据当前的模式展示不同的颜色,而原有的 lightContent 样式则新增一个 darkContent 的样式与之对应。

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {

UIStatusBarStyleDefault      = 0, // Automatically chooses light or dark content based on the user interface style

UIStatusBarStyleLightContent = 1, // Light content, for use on dark backgrounds

UIStatusBarStyleDarkContent  = 3, // Dark content, for use on light backgrounds

};

参考资料:

How To Adopt Dark Mode In Your iOS App

Backwards compatibility for iOS 13 system colors

写给设计师的指南:iOS 13 Dark Mode 深度解析

作者简介

就职于甜橙金融(翼支付)信息技术部,负责 iOS 客户端开发。

iOS 13 DarkMode 暗黑模式相关推荐

  1. iOS开发 DarkMode 暗黑模式

    一.开发环境 Xcode11 正式版 iOS13 beta版本 Mac系统: 10.15 beta版本 二.适配原理 将同一个资源,创建出两种模式的样式.系统根据当前选择的样式,自动获取该样式的资源. ...

  2. iOS 13.0 暗黑模式的适配

    一.暗黑模式的原理 将原本的资源文件,创建出两种不同的模式.根据不同的模式,自动获取该样式的资源. 每次切换系统模式的时候,系统会重新调用一些方法,重新赋值. 二.暗黑模式适配主要考虑的是: 1. 图 ...

  3. iOS 13适配——暗黑模式

    暗黑模式介绍 Implementing Dark Mode on iOS How To Adopt Dark Mode In Your iOS App Adopting iOS Dark Mode S ...

  4. 微信联合苹果探索iOS系统的暗黑模式;iPhone SE 2于3月31日发布;Kotlin 1.3.70发布 | 极客头条...

    整理 | 郭芮 头图 | CSDN 下载自东方 IC 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦 ...

  5. 微信iOS版内测暗黑模式;涉嫌恶意举报,社交平台Soul运营合伙人被批捕;AWS推出基于Linux开源操作系统 | 极客头条...

    整理 | 屠敏 头图 | CSDN 下载自东方 IC 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦 ...

  6. iOS 13的黑暗模式如何在iPhone和iPad上运行

    Khamosh Pathak Khamosh Pathak With iOS 13 and iPadOS 13, Apple is finally bringing a system-wide dar ...

  7. iOS开发关闭暗黑模式

    全局关闭暗黑模式 1.在info.plist文件中,添加UIUserInterfaceStyle key名字为User Interface Style 值为String, 2.将UIUserInter ...

  8. iOS强制关闭暗黑模式

    发现之前很多人说的 在info.plist文件中添加key:User Interface Style,值类型是String,值为Light,重新运行项目即可: 上面我试了发现不管用. 后来找到了如下方 ...

  9. iOS 暗黑模式适配(项目实战篇)

    通过上面两篇文章,我们知道了暗黑模式怎么去适配,那么如何结合到真实的项目场景中去呢? 适配目标 在项目适配之前,先来梳理一下需要适配的东西,以及可能预见的问题. 一.下图是我们单个App的控件适配目标 ...

最新文章

  1. ignite服务中的bean注入为空
  2. 云上人替代方案训练代码
  3. Windows系统笔记本禁用自带键盘
  4. java勇者大冒险_勇者大冒险 第一集 开车时英文歌 什么名
  5. 第二专业 计算机考试成绩查询系统,2021年上半年信息系统项目管理师成绩查询时间公布(7月12日),查询入口已开通!...
  6. 第十章:在Spark集群上掌握比较重要的图操作之Computing Degree
  7. JsonPath小结
  8. 《JavaScript 高级程序设计(第四版)》
  9. 傅里叶变换【2】:傅里叶幅度谱与相位谱
  10. 00 后搞视频号月入过万,怎么做?
  11. 【OpenGrok代码搜索引擎】二、Windows10下基于Linux子系统搭建Opengrok代码搜索引擎
  12. 如何从零开始学python_《如》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
  13. Linux下git clone速度奇慢的有效解决办法(亲测有效)
  14. 曝光!中国女性的私密数据分析…
  15. 热招 | 我们是 Towhee 产研团队
  16. vue--后台管理系统问题和功能实现思路集锦
  17. 关于chrome、360浏览器自动填充的黄色背景处理方案
  18. 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原
  19. sqlserver 查看服务器名称以及sql语句跨服务器查询设置
  20. PMP自学不报班5A通过经验总结(附PMBOK高清电子书完整书签)

热门文章

  1. 高性能、可扩展、跨平台的实用工具 Gloo 亮相 DockerCon,现代化应用即可拥有!...
  2. 通达信反映资金变化资金趋势的指标公式源码
  3. bzoj2215: [Poi2011]Conspiracy
  4. 获取富文本编辑器的纯文本内容
  5. python缺少位置参数_缺少1个必需的位置参数
  6. 【算法•日更•第十五期】信息奥赛一本通1594:涂抹果酱题解
  7. 关闭Eslint中的规则 no-unused-vars
  8. [渝粤教育] 浙江大学 2021秋冬管理学(施杰2) 参考 资料
  9. 福州大学2021知识产权线上课程期末考试答案
  10. [UESTC 1061]秋实大哥与战争