如何使用 UserDefaults 保存 UIColor?

How do I save a UIColor with UserDefaults?

我正在尝试对我的代码进行编程,以便在用户按下“夜间”按钮时背景将变为黑色并在用户关闭应用程序时保持黑色。 (白天模式也是如此。)

请注意:我已经对按钮进行了编码,当他们按下它时,所有场景都会更改为该模式。

这是我需要保存背景颜色的代码:(我在两个 if 语句中都需要它)

if GlobalData.dayBool == true && GlobalData.night == false {
    backgroundColor = GlobalData.dayColor 
}

if GlobalData.nightBool == true && GlobalData.dayBool == false {
    backgroundColor = GlobalData.nightColor 
}

我的昼夜颜色:

struct GlobalData {
    static var score = 0
    static var dayColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0)
    static var nightColor = UIColor(red:0.10, green:0.10, blue:0.10, alpha:1.0)  
    static var dayBool = true
    static var nightBool = true
}

最简单的方法是使用 NSUserDefaults

简单的例子-

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Coding Explorer", forKey: "userNameKey")

在这种情况下,您正在存储字符串 "Coding Explorer",您可以通过键 "userNameKey" 进行引用。我相信您可以看到如何将其应用到您的解决方案中:P

帮助您入门的好资源here

如果您想要更健壮的东西,请看一下 CoreData,但是实现稍微复杂一些。 CoreData 可能不是简单状态持久化所需的,但仍然值得研究。

Link here

编辑

Here is a great example to look at how you can save the actual color to NSUserData

Swift 5.2 或更高版本

请注意,这只会将 RGBA CGFloat 值保存为 属性 列表中的数据。这将使用 32 个字节(原始数据)而不是使用 NSKeyedUnarchiver (NSCoding) 的标准方法时所需的 424 个字节:

extension Numeric {
    var data: Data {
        var bytes = self
        return Data(bytes: &bytes, count: MemoryLayout<Self>.size)
    }
}

extension Data {
    func object<T>() -> T { withUnsafeBytes{[=11=].load(as: T.self)} }
    var color: UIColor { .init(data: self) }
}

extension UIColor {
    convenience init(data: Data) {
        let size = MemoryLayout<CGFloat>.size
        self.init(red:   data.subdata(in: size*0..<size*1).object(),
                  green: data.subdata(in: size*1..<size*2).object(),
                  blue:  data.subdata(in: size*2..<size*3).object(),
                  alpha: data.subdata(in: size*3..<size*4).object())
    }
    var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)? {
        var (red, green, blue, alpha): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)
        return getRed(&red, green: &green, blue: &blue, alpha: &alpha) ?
        (red, green, blue, alpha) : nil
    }
    var data: Data? {
        guard let rgba = rgba else { return nil }
        return rgba.red.data + rgba.green.data + rgba.blue.data + rgba.alpha.data
    }
}

extension UserDefaults {
    func set(_ color: UIColor?, forKey defaultName: String) {
        guard let data = color?.data else {
            removeObject(forKey: defaultName)
            return
        }
        set(data, forKey: defaultName)
    }
    func color(forKey defaultName: String) -> UIColor? {
        data(forKey: defaultName)?.color
    }
}

extension UserDefaults {
    var backgroundColor: UIColor? {
        get { color(forKey: "backgroundColor") }
        set { set(newValue, forKey: "backgroundColor") }
    }
}

UserDefaults.standard.backgroundColor = .red
UserDefaults.standard.backgroundColor  // r 1.0 g 0.0 b 0.0 a 1.0