Swift:适配深色模式与UIColor扩展

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

前言

今天简单聊一下适配深色模式的事情,其实我在这方面没干什么大事,经验不多。

大家有什么好的思路与想法欢迎分享。

配置info.plist锁死模式

如果你的App在之前的iOS版本跑的挺好的,特别是那种浅色系风格的App,只是在深色模式下变得奇丑无比的话,有一种简单暴力的方法去适配深色模式。

那就是将你的App锁死在浅色模式或者黑色模式。这样无论外面设置怎么修改,App的配色岿然不动。

修改的方法也特别简单,在App中info.plist文件,添加如下代码就可以了。

锁死浅色:

<key>UIUserInterfaceStyle</key>
<string>Light</string>
复制代码

锁死深色:

<key>UIUserInterfaceStyle</key>
<string>Dark</string>
复制代码

如果你要比较细化的适配浅色和深色,请接着往下看。

UIColor分类

  • 抽取一个构造方法,可以传入浅色与深色的方法,生成一个UIColor,我的方法如下:
//MARK: - LightMode与DarkMode的颜色思路
extension UIColor {

    /// 便利构造函数(配合cssHex函数使用 更好)
    /// - Parameters:
    ///   - lightThemeColor: 明亮主题的颜色
    ///   - darkThemeColor: 黑暗主题的颜色

    public convenience init(lightThemeColor: UIColor, darkThemeColor: UIColor? = nil) {
        if #available(iOS 13.0, *) {
            self.init { (traitCollection) -> UIColor in
                switch traitCollection.userInterfaceStyle {
                    case .light:
                        return lightThemeColor
                    case .unspecified:
                        return lightThemeColor
                    case .dark:
                        return darkThemeColor ?? lightThemeColor
                    @unknown default:
                        fatalError()
                }
            }
        } else {
            self.init(cgColor: lightThemeColor.cgColor)
        }
    }
}
复制代码
  • 最好对于App类常用的颜色都进行UIColor的分类扩展编写。比如下面这种:
extension UIColor {

    /// 文字颜色 light为黑 dark为白
    static let playAndroidTitle = UIColor(lightThemeColor: .black, darkThemeColor: .white)

    /// 背景颜色 light为白 dark为黑
    static let playAndroidBg = UIColor(lightThemeColor: .white, darkThemeColor: .black)

}
复制代码

使用的时候这样就可以了:

let label = UILabel()

label.textColor = .playAndroidTitle
复制代码

我的wanandroid客户端就是这么改造完成的,当然我这是一个新项目,所以做起深色模式相比较而言会容易一些。

不过我觉得就算是旧项目,适配深色模式的首要任务依旧是抽离、归纳、整理App中所有的颜色,然后在配合UI进行整改。

UIColor的colorName API使用

另外我们可以通过iOS 11之后的新API与配置方法进行深色模式的适配:

  1. 先在Assets新建色彩资源:

image.png

2.设置好颜色配置。

3.调用

系统API如下:

extension UIColor {
    @available(iOS 11.0, *)
    public /*not inherited*/ init?(named name: String) // load from main bundle

    @available(iOS 11.0, *)
    public /*not inherited*/ init?(named name: String, in bundle: Bundle?, compatibleWith traitCollection: UITraitCollection?)

}
复制代码

编写分类:

extension UIColor {
    
    /// UIColor的原始调用,硬编码不够安全,而且返回的还是一个可选类型,需要注意
    /// 可以考虑使用R函数
    static let theme = UIColor.colorNamed("mainTheme")
}
复制代码

总结

本文针对适配深色模式进行3种方式的解决方案:

  • 强制模式,通过info.plist配置完成。

  • 编写UIColor分类,编写分类函数完成。

  • 在工程中的Assets添加颜色资源文件,并调用API进行,注意这种方式适合iOS 11之后。

我们下期见。

猜你喜欢

转载自juejin.im/post/7014437997869432868