在 SwiftUI 中添加 Dark Mode 最佳实践
了解如何在 SwiftUI 中为应用添加黑暗模式,并学习如何使颜色能够自适应外观模式而切换。
使用 SwiftUI 开发 iOS 应用,添加黑暗模式效果非常简单,SwiftUI 提供了自动适应系统外观变化的能力,在大部分情况下,你无需格外工作即可自动应用黑暗模式。
但在实践中,仍然存在一些使用技巧和颜色搭配原则,遵循这些技巧和原则,可以让应用表现更加出众。
颜色搭配原则
巧妙地使用颜色可以增强沟通感,体现品牌形象,提供视觉连续性,传达状态和反馈,以及帮助用户理解信息。
Apple 颜色设计规范:
Dark Mode 设计原则:
优先使用系统自适应颜色
如果使用指定颜色(例如 Color.white),会导致组件无法自动适配系统的浅色/深色模式而动态变化。
在下面这个示例中,最开始我使用 .background(Color.white)
为卡片设置了白色的背景色。这在浅色模式下表现良好,但当开启黑暗模式,就会显得非常突兀,因为 Color.white
不会自适应外观模式进行调整:
为了解决这个问题,推荐优先使用 Color 的自适应系统颜色,这些颜色会自动根据当前的外观模式(Light Mode 和 Dark Mode)进行调整。
例如,使用Color(.systemBackground)
,能够保证在浅色模式和深色模式下都有很好的可读性:
Apple 原生应用风格的颜色搭配最佳实践
Apple 推荐的背景色与前景色,在不同外观模式下的搭配是这样的:
在浅色模式下:
- 系统背景为浅灰色。
- 内容块背景为纯白色。
在深色模式下:
- 系统背景为纯黑色。
- 内容块背景为浅灰色。
iPhone 上的几乎所有 Apple 原生应用,都遵循这套颜色使用原则。
为了实现以上效果,可以组合使用:
.background(Color(.systemGroupedBackground)) (用作系统背景颜色)
.background(Color(.secondarySystemGroupedBackground)) (用作内容块背景颜色)
例如下面这个实例代码:
import SwiftUI
struct SettingsView: View {
var body: some View {
List {
Section(header: Text("账号设置")) {
HStack {
Text("用户名")
Spacer()
Text("john_doe")
.foregroundColor(.gray)
}
HStack {
Text("电子邮箱")
Spacer()
Text("john@example.com")
.foregroundColor(.gray)
}
}
.background(Color(.secondarySystemGroupedBackground))
Section(header: Text("应用设置")) {
Toggle("推送通知", isOn: .constant(true))
Toggle("使用蜂窝数据", isOn: .constant(false))
}
.background(Color(.secondarySystemGroupedBackground))
Section(header: Text("隐私")) {
NavigationLink(destination: Text("隐私政策详情")) {
Text("隐私政策")
}
NavigationLink(destination: Text("条款与条件")) {
Text("条款与条件")
}
}
.background(Color(.secondarySystemGroupedBackground))
}
.listStyle(GroupedListStyle())
.background(Color(.systemGroupedBackground))
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
.preferredColorScheme(.light) // 预览浅色模式
SettingsView()
.preferredColorScheme(.dark) // 预览深色模式
}
}
自适应外观模式颜色列表
SwiftUI 提供了许多能够自动适应系统外观模式(浅色和深色模式)的颜色,这些颜色会根据用户的设置自动调整,以确保在不同的环境下都有良好的可读性和一致的视觉体验。
以下是 SwiftUI 中常用的自适应外观模式的颜色,每个颜色在不同外观模式下的表现,可以参考附录。
文本颜色
Color.primary
用途:主要内容的前景色,通常用于文本。
效果:浅色模式下为黑色,深色模式下为白色。
Color.secondary
用途:次要内容的前景色,比 primary 更淡。
效果:颜色会根据模式自动调整。
Color.accentColor
用途:应用的强调色,可用于按钮、链接等需要突出的元素。
设置:可在 Assets.xcassets 中全局设置。
系统背景颜色
Color(.systemBackground)
用途:视图的背景色。
效果:浅色模式下为白色,深色模式下为黑色。
Color(.secondarySystemBackground)
用途:次级内容的背景色。
效果:颜色会根据模式自动调整。
Color(.tertiarySystemBackground)
用途:分组内容的背景色。
系统分组背景颜色
Color(.systemGroupedBackground)
用途:用于分组列表的背景。
Color(.secondarySystemGroupedBackground)
用途:次级分组背景色。
Color(.tertiarySystemGroupedBackground)
用途:三级分组背景色。
标签颜色
Color(.label)
用途:主要文本颜色。
Color(.secondaryLabel)
用途:次要文本颜色。
Color(.tertiaryLabel)
用途:三级文本颜色。
Color(.quaternaryLabel)
用途:四级文本颜色。
填充颜色
Color(.systemFill)
用途:含有内容的元素的背景色,例如输入框。
Color(.secondarySystemFill)
用途:次级填充色。
Color(.tertiarySystemFill)
用途:三级填充色。
Color(.quaternarySystemFill)
用途:四级填充色。
分隔线颜色
Color(.separator)
用途:一般分隔线颜色。
Color(.opaqueSeparator)
用途:不透明的分隔线颜色。
链接颜色
Color(UIColor.link)
用途:可点击的链接文本颜色。