Swift中如何优雅的适配黑夜模式(dark mode)
参考资料:
动态颜色
iOS13 往后,UIColor类增加如下方法:
extension UIColor {
@available(iOS 13.0, *)
public init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)
}
我们可以使用这个方法来创建动态颜色,但是使用的时候总要判断iOS版本号。
为了避免麻烦,我写了个ColorUtil类
class ColorUtil {
public class func dynamicColor(dark:UIColor, light:UIColor) -> UIColor {
if #available(iOS 13, *) { // 版本号大于等于13
return UIColor { (traitCollection: UITraitCollection) -> UIColor in
return traitCollection.userInterfaceStyle == UIUserInterfaceStyle.dark ?
dark : light
}
}
return light
}
}
监听模式变化
可以通过如下UIViewController.traitCollectionDidChange来监听:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
if #available(iOS 13, *) {
if self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
if self.traitCollection.userInterfaceStyle == .dark {
// 黑夜模式
} else {
// 白天模式
}
}
}
}
给导航栏(NavigationBar)设置动态颜色
修改NavigationBar的样式有两种方式:
- 修改
NavigationBar.backgroundColor - 通过
NaivgationBar.setBackgroundImage(UIImage?, for: UIBarMetrics)设置背景图片
如果使用修改backgroundColor的方法,由于背景图会覆盖在上面,所以需要考虑将背景图片设置成nil即:
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationController?.navigationBar.backgroundColor = yourDynamicColor
如果使用修改背景图片的方法,则不能使用动态颜色,而应该在traitCollectionDidChange中动态修改背景图片。