文章

在您的界面中支持深色模式

更新颜色、图像和行为,让您的 app 在深色模式激活时自动进行调整。

概览

在 macOS 和 iOS 中,用户可以选择采用系统范围的浅色或深色外观。深色外观也称为“深色模式”,这种外观会实施很多 app 已在采用的一种界面风格。用户可以选择他们喜爱的审美风格,也可以选择根据环境光照条件或具体时间表来切换界面。

系统在“日历”app 和 Xcode 的文档查看器中显示深色外观。

所有 app 都应同时支持浅色和深色界面风格,但在某些位置使用特定的外观或许效果更佳。例如,对于打印的内容,您可能总是会采用浅色外观。

在更改您的代码前,请打开深色模式并查看 app 的响应情况。系统会替您完成许多工作,如果您的 app 使用标准的视图和控件,您可能不需要进行太多更改。标准视图和控件会自动更新外观来与当前的的界面风格保持一致。如果已在使用颜色和图像素材,您可以添加深色变体,而无需更改您的代码。

图像显示了 macOS 中“系统偏好设置”app 的“通用”面板,用户可以在这个面板中启用深色模式。

为您的 UI 选择自适应颜色

选择可自动适应基础界面风格的颜色。浅色和深色界面使用迥然不同的调色盘。在浅色外观中表现良好的颜色或许在深色外观中难以看清,反之亦然。自适应颜色对象可以针对不同的界面风格返回不同的颜色值。

您可以通过以下两种方式创建自适应颜色对象:

  • 选择语义颜色,而非固定颜色值。在配置 UI 元素时,选择具有 labelColor 等名称的颜色。这样的语义颜色传递颜色的预期用途,而不是具体的颜色值。在用于预期的用途时,它们会使用适合当前设置的颜色值进行渲染。有关语义颜色名称的完整列表,请参阅 NSColor (英文)UIColor (英文)

  • 在素材目录中定义自定颜色。在您需要特定的颜色时,以颜色素材的形式创建这种颜色。在您的素材中,为浅色和深色外观指定不同的颜色值。您也可以指定颜色的高对比度版本。

您可以使用 Xcode 的素材编辑器配置自定颜色素材。在项目中添加“Color Set”(颜色集) 素材,然后配置您要修改的外观变体。使用“Any Appearance”(任意外观) 变体可以指定要在不支持深色模式的旧系统上使用的颜色值。

图像中显示了用于为浅色和深色内容添加颜色槽的外观选项。

要从素材目录中载入颜色值,请通过名称来载入颜色:

// macOS
let aColor = NSColor(named: NSColor.Name("customControlColor"))

// iOS
let aColor = UIColor(named: "customControlColor")

从颜色素材创建颜色对象时,您不必在当前外观改变时重新创建这个对象。每当您为绘图设定填充或笔画颜色时,颜色对象会载入与当前环境设置匹配的颜色变体。labelColor 等语义颜色同样如此,这些颜色会自动适应当前的环境。相反,使用固定分量值创建的颜色对象不会进行调整,您必须创建新的颜色对象。

创建适合所有外观的图像

确保界面中的图像在浅色和深色外观中都有良好的效果。界面在许多位置上使用图像,包括按钮、图像视图以及自定视图和控件。如果图像在外观更改后难以看清,请提供在其他外观中拥有良好效果的新图像素材。更好的是使用符号图像或模板图像,它们仅定义要渲染的形状,因此不需要对浅色、深色和高对比度环境使用不同的图像。

有关为浅色和深色界面配置图像的信息,请参阅“提供适合不同外观的图像 (英文)”。

使用特定的方法更新自定视图

在用户更改系统外观时,系统会自动要求每个窗口和视图重绘自身。在这个过程中,系统会调用适用于 macOS 和 iOS 的几个常见方法 (如下表中所列) 来更新您的内容。系统会在调用这些方法前更新特征环境;这样,如果您在这些方法中进行所有对外观敏感的更改,您的 app 就能正确地更新自身。

如果您在这些方法之外进行对外观敏感的更改,您的 app 可能无法针对当前的环境正确绘制它的内容。这时可让您的代码改为调用这些方法。例如,不要在创建时设置 NSView (英文) 对象图层的背景颜色,而应将这段代码移到视图的 updateLayer() (英文) 方法中,如下方代码示例中所示。在创建时设置背景颜色看起来似乎合理,但因为 CGColor (英文) 对象不会进行调整,在创建时设置背景颜色会使视图具有固定不变的背景颜色。将代码移到 updateLayer() 后,每当环境改变时就会自动刷新背景颜色。

override func updateLayer() {
   self.layer?.backgroundColor = NSColor.textBackgroundColor.cgColor

   // Other updates.
}

根据预期用途选择视觉效果材质

视觉效果视图为您的背景视图增添透明度,让您的 UI 具有比背景不透明时更强的视觉深度。为确保您的内容保持可见,视觉效果视图会细微地模糊背景内容并添加振动效果,从而自动调整前景内容的颜色。系统会动态地更新这些效果,确保您的 app 内容在基础内容改变时保持可见。

以容器视图的形式在界面中使用视觉效果视图,并为它们添加子视图来代表前景内容。使用适合您所需外观的材质或效果,配置每个视觉效果视图:

仅在需要时停用

尽量在您的 app 中同时采用浅色和深色外观。如果支持某种外观对您 app 的全部或部分区域没有意义,您可以选择在相应的窗口或视图中停用外观更改。例如,对于 app 的打印视图,您可能总是会采用浅色外观。

您可以配置界面的全部或部分区域来停用特定的外观。您也可以对您的整个 app 采用特定的外观。有关更多信息,请参阅以下资源:

在外观过渡时避免高开销任务

用户在浅色和深色界面之间切换时,系统会要求您的 app 重绘它的所有内容。虽然系统会管理绘制过程,但在这个过程中的几个时间点上依赖于您的自定代码。您的代码必须能够尽可能快地运行,而且不执行与外观更改无关的任务。在 macOS 中,AppKit 通常会在外观更改过程中创建过渡动画,但是如果您的 app 重绘自身用时太长,它会忽略这些动画。

相关主题

外观支持

为您的 macOS App 选择特定的外观 (英文)

在不适合同时支持浅色和深色变体时,为您的窗口、视图或 app 采用特定的外观。

为您的 iOS App 选择特定的界面风格 (英文)

在不适合同时支持浅色和深色变体时,为您的窗口、视图控制器或 app 采用特定的界面风格。

图像

提供适用于不同外观的图像 (英文)

提供适用于浅色和深色外观以及高对比度环境的图像资源。

在您的 UI 中配置和显示符号图像

创建可与 app 中文本良好整合的可缩放图像,并动态调整这些图像的外观。