简短的回答
在这种情况下,您需要指定使用哪个特征集合来解析动态颜色。
self.traitCollection.performAsCurrent {
self.layer.borderColor = UIColor(named: "testColor")?.cgColor
}
或者
self.layer.borderColor = UIColor(named: "testColor")?.resolvedColor(with: self.traitCollection).cgColor
更长的答案
当您cgColor
在 dynamic 上调用该方法时UIColor
,它需要解析动态颜色的值。这是通过引用当前特征集合来完成的,UITraitCollection.current
.
当前的特征集合是由 UIKit 在调用某些方法的覆盖时设置的,特别是:
- 界面视图
- 画()
- 布局子视图()
- traitCollectionDidChange()
- tintColorDidChange()
- UIViewController
- viewWillLayoutSubviews()
- viewDidLayoutSubviews()
- traitCollectionDidChange()
- UIPresentationController
- containerViewWillLayoutSubviews()
- containerViewDidLayoutSubviews()
- traitCollectionDidChange()
但是,在这些方法的覆盖之外,当前特征集合不一定设置为任何特定值。因此,如果您的代码没有覆盖这些方法之一,并且您想要解析动态颜色,那么您有责任告诉我们要使用什么特征集合。
(这是因为可以覆盖userInterfaceStyle
任何视图或视图控制器的特征,因此即使设备可能设置为亮模式,您也可能拥有处于暗模式的视图。)
您可以通过使用 UIColor 方法直接解析动态颜色来做到这一点resolvedColor(with:)
。或者使用 UITraitCollection 方法performAsCurrent
,并将解析颜色的代码放在闭包内。上面的简短回答显示了两种方式。
您还可以将您的代码移动到其中一种方法中。在这种情况下,我认为您可以将其放入layoutSubviews()
. 如果你这样做,它会在明暗风格改变时自动被调用,所以你不需要做任何其他事情。
参考
WWDC 2019,在 iOS 中实现暗模式
Starting at 19:00 I talked about how dynamic colors get resolved, and at 23:30 I presented an example of how to set a CALayer
's border color to a dynamic color, just like you're doing.