iOS 11 以下命名颜色的兼容性

Art*_*aev 5 xcode ios ios8 xcode11

我需要在运行在 iOS 8+ 上的 iOS 应用程序中实现暗模式。此外,我在颜色资产中定义了自定义颜色,其中包含用于浅色和深色外观的 RGB 代码。

问题是 iOS 11 之前不支持命名颜色,但我只能使用命名颜色来支持两种外观 - 深色和浅色。

有没有办法实现向后兼容?

Aya*_*mon 5

使用颜色资产时不能这样做。但是,您可以创建自己ThemeManger的主题来处理应用程序的主题。

首先创建一个ThemeManager. 它的主要目的是保存style应用程序的。

class ThemeManager {

    static let shared: ThemeManager = ThemeManager()

    var style: ThemeStyle = .light 
}
Run Code Online (Sandbox Code Playgroud)

这里ThemeStyle应该是一个包含您的主题(浅色、深色等)的枚举。

创建一个ThemeColor类来处理您的颜色

class ThemeColor {
    var dark: UIColor = UIColor.clear
    var light: UIColor = UIColor.clear
    var asset: String = ""    

    func getColor(for theme: ThemeStyle = ThemeManager.shared.style) -> UIColor {
        if #available(iOS 13.0, *) {
            if asset != "", let assetColor = UIColor(named: asset) {
                return assetColor
            }
        }
        if theme == .dark {
            return dark
        }

        return light
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用该getColor功能获取所需的颜色。请注意,ThemeColor返回assetiOS 13的颜色值。这是为了在用户从设置中更改他/她的偏好时更改应用程序的主题。

例子:


extension UIColor {
    class var backgroundColor: ThemeColor {
        let themeColor = ThemeColor()
        themeColor.light = UIColor.white
        themeColor.dark = UIColor.black
        themeColor.asset = "backgroundColor"

        return themeColor
    }
}

// Somewhere in your code set the backgroundColor of your view
myView.backgroundColor = UIColor.backgroundColor.getColor()

Run Code Online (Sandbox Code Playgroud)
  • 要完成这项工作,您需要根据用户对 iOS 13 设备的偏好更新您的style变量ThemeManger。你可以通过traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)在你的UIViewController类中实现这个方法来做到这一点。
  • 就像backgroundColor示例一样,您需要定义受主题更改影响的所有颜色。
  • style您的值设置ThemeManger为您的首选,style以便您的应用程序在未在 iOS 13 上运行时以其默认主题打开。

编辑:如果您的用户将无法从程序本身内改变的应用在自己的主题,那么你不需要lightdark的UIColor值ThemeColor。只需定义一个defaultColor值并在getColor函数结束时返回它。这将允许您的应用出现在运行 iOS 12 或更低版本的设备的默认主题中。