在深色或浅色模式下管理颜色的最佳方式
The best way to manage colours in dark or light mode
在工作中,我们有一个颜色设计系统,例如
红-1
红2
红 3
绿色-1
绿2
绿色-3
它们背后的十六进制代码可能会发生变化,但一个组件或一组组件也可能会发生变化,例如,将它们的颜色从 red-1 更改为 red-2。
我们还想处理深色模式。在浅色模式下,您的背景可能为 red-1,但在深色模式下,它需要为 green-1。这意味着我们可能还需要语义颜色,例如:
background-1(浅色模式为红色1,深色模式为绿色1)
前景 1
等等
我知道用最少的样板来处理黑暗模式的最简单方法是使用资产目录。因此,您将拥有一个名为 background-1 的颜色资产,并且具有深色和浅色模式颜色。
问题是,该颜色无法引用其他自定义颜色(如 red-1)。相反,您必须手动输入十六进制代码,这意味着如果 red-1 发生变化,您将非常头疼地更改所有使用 red-1 的语义颜色。
另一方面,据我所知,如果您走程序化路线(即为您的 red-1、green-1 使用资产目录,并为您的语义使用 class/enum颜色)你需要为每个使用这些颜色的 class 添加大量样板(我认为是 traitCollectionDidChange?)。
有谁能想到一个快乐的媒介吗?如果存在外部工具,很乐意使用。
编辑:我有一个想法:
- Colors.xcassets - 这有我们的语义颜色
- ColorSystem.json - 这有真实的颜色和它们的六边形(red-1 等)
- ColorMap.json - 这是两者的结合
- 构建阶段脚本以获取 ColorSystem.json 和 ColorMap.json 并将两者结合以生成一个新的 Colors.xcassets 系统。
然后每当我们改变十六进制时,我们就改变ColorMap.json。每当我们更改语义颜色以使用不同的“真实”颜色时,我们都会更改 ColorMap.json.
也许我误解了你的确切问题,但是你如何将你的颜色类型添加到你的资产中。这些通常被定义为“主要”“次要”等。但您可以将它们添加为“red1”、“red2”等。
然后在代码中,您可以在 UIColor
扩展中设置这些资产,例如:
extension UIColor {
// MARK: Colors set in assets folder
static var red1: UIColor {
UIColor(named: "red1") ?? .red // Named returns an optional, so default
}
static var red2: UIColor {
UIColor(named: "red1") ?? .red // Named returns an optional, so default
}
static var black1: UIColor {
UIColor(named: "black1") ?? .black
}
// MARK: - My predefined colors
static var primaryBackground: UIColor {
.red1
}
static var primaryText: UIColor {
.black1
}
static var highlightedText: UIColor {
.red1
}
static var secondaryBackground: UIColor {
.red2
}
}
red1
、red2
的黑暗模式值等您将在资产文件夹中定义。
现在在您的代码中,您只需按以下方式访问它们:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .primaryBackground
}
更新
不同模式的不同颜色处理在资产目录中完成。在下面的示例中,它被称为“Background primary”而不是“red1”;但你可以随便称呼它。
您可以根据品牌的颜色配置文件(声明主要、次要行为)定义资产目录中的颜色,或者定义您在此处使用的颜色(例如红色、黄色、绿色行为),然后在您的代码如上所述。
第一种是“正确”的做法,因为您将定义在应用程序中重复使用的类别。例如,在亮模式下将背景设置为红色,在暗模式下设置为绿色,您将 select 应用程序中的“背景”颜色,而不是红色或绿色。
做资产目录所做的事情,而不实际使用资产目录。使用 UIColor 动态提供程序初始化程序将您的颜色完全在代码中定义为亮/暗模式对:
https://developer.apple.com/documentation/uikit/uicolor/3238041-init
现在继续在整个应用程序中使用这些颜色。无需知道您是处于亮模式还是暗模式。不需要“开销”。您的颜色将自动始终适合当前模式,并会在用户在明暗模式之间切换时自动更改。
在工作中,我们有一个颜色设计系统,例如
红-1 红2 红 3
绿色-1 绿2 绿色-3
它们背后的十六进制代码可能会发生变化,但一个组件或一组组件也可能会发生变化,例如,将它们的颜色从 red-1 更改为 red-2。
我们还想处理深色模式。在浅色模式下,您的背景可能为 red-1,但在深色模式下,它需要为 green-1。这意味着我们可能还需要语义颜色,例如:
background-1(浅色模式为红色1,深色模式为绿色1) 前景 1
等等
我知道用最少的样板来处理黑暗模式的最简单方法是使用资产目录。因此,您将拥有一个名为 background-1 的颜色资产,并且具有深色和浅色模式颜色。
问题是,该颜色无法引用其他自定义颜色(如 red-1)。相反,您必须手动输入十六进制代码,这意味着如果 red-1 发生变化,您将非常头疼地更改所有使用 red-1 的语义颜色。
另一方面,据我所知,如果您走程序化路线(即为您的 red-1、green-1 使用资产目录,并为您的语义使用 class/enum颜色)你需要为每个使用这些颜色的 class 添加大量样板(我认为是 traitCollectionDidChange?)。
有谁能想到一个快乐的媒介吗?如果存在外部工具,很乐意使用。
编辑:我有一个想法:
- Colors.xcassets - 这有我们的语义颜色
- ColorSystem.json - 这有真实的颜色和它们的六边形(red-1 等)
- ColorMap.json - 这是两者的结合
- 构建阶段脚本以获取 ColorSystem.json 和 ColorMap.json 并将两者结合以生成一个新的 Colors.xcassets 系统。
然后每当我们改变十六进制时,我们就改变ColorMap.json。每当我们更改语义颜色以使用不同的“真实”颜色时,我们都会更改 ColorMap.json.
也许我误解了你的确切问题,但是你如何将你的颜色类型添加到你的资产中。这些通常被定义为“主要”“次要”等。但您可以将它们添加为“red1”、“red2”等。
然后在代码中,您可以在 UIColor
扩展中设置这些资产,例如:
extension UIColor {
// MARK: Colors set in assets folder
static var red1: UIColor {
UIColor(named: "red1") ?? .red // Named returns an optional, so default
}
static var red2: UIColor {
UIColor(named: "red1") ?? .red // Named returns an optional, so default
}
static var black1: UIColor {
UIColor(named: "black1") ?? .black
}
// MARK: - My predefined colors
static var primaryBackground: UIColor {
.red1
}
static var primaryText: UIColor {
.black1
}
static var highlightedText: UIColor {
.red1
}
static var secondaryBackground: UIColor {
.red2
}
}
red1
、red2
的黑暗模式值等您将在资产文件夹中定义。
现在在您的代码中,您只需按以下方式访问它们:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .primaryBackground
}
更新 不同模式的不同颜色处理在资产目录中完成。在下面的示例中,它被称为“Background primary”而不是“red1”;但你可以随便称呼它。 您可以根据品牌的颜色配置文件(声明主要、次要行为)定义资产目录中的颜色,或者定义您在此处使用的颜色(例如红色、黄色、绿色行为),然后在您的代码如上所述。
第一种是“正确”的做法,因为您将定义在应用程序中重复使用的类别。例如,在亮模式下将背景设置为红色,在暗模式下设置为绿色,您将 select 应用程序中的“背景”颜色,而不是红色或绿色。
做资产目录所做的事情,而不实际使用资产目录。使用 UIColor 动态提供程序初始化程序将您的颜色完全在代码中定义为亮/暗模式对:
https://developer.apple.com/documentation/uikit/uicolor/3238041-init
现在继续在整个应用程序中使用这些颜色。无需知道您是处于亮模式还是暗模式。不需要“开销”。您的颜色将自动始终适合当前模式,并会在用户在明暗模式之间切换时自动更改。