使UIColor可编码-符合协议“ Encodable”

时间:2019-07-05 11:36:07

标签: swift encoding uicolor

我很难编码和加载plist中的可转换颜色数据,而该plist以前没有从代码中加载的困难。

在UIColor的扩展中,结构以及编码器和解码器中的可用颜色数量有限。

extension UIColor
{
struct Words
{
    static let verb = UIColor(netHex: 0xff0000)
    static let noun = UIColor.blue
    static let subject = UIColor(netHex: 0x0000ff)
    static let object = UIColor(netHex: 0x1e5900)
    static let indirectObject = UIColor(netHex: 0x369d01)
    static let genitive = UIColor(netHex: 0x783f04)
    static let article = UIColor(netHex: 0xff6500)
    static let adjective = UIColor(netHex: 0x9900ff)
    static let adverb = UIColor(netHex: 0xff00ff)
    static let generic = UIColor(netHex: 0x70747a)
}

class func color(data:Data) -> UIColor? {
    return try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? UIColor
}

func encode() -> Data? {
    return try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
}
}

在我的代码模型中(可行),我只是定义了颜色的文本值:

var color1: String?
... 
color1 = subject // etc

在一种方法中,将编码后的数据加载到数据库中:

let myColorData = myColor1.encode()

然后在collection view cellForItemAt indexPath中,我可以访问颜色数据,该颜色数据用于为文本(未显示)添加属性。

let color1 = UIColor.color(data: cellData.color1 as! Data)

当我从pList加载而不是从代码加载数据时,就会出现问题。数据似乎已加载到Core Data中,但该应用程序仍然崩溃,并显示错误:

  • 无法将类型'NSTaggedPointerString'(0x108cc0560)的值强制转换为'UIColor'

我认为这意味着UIColor没有被编码(?),尽管它确实确实将某些“斑点”加载到了数据库中。

如果我遵循Make UIColor Codable的建议,并且类似,但我不断收到错误消息。

  • 在“可选”上引用实例方法“ encode(to :)”要求“ UIColor”符合“可编码”。

我想我需要使我的结构词:Codable,但是我不确定这是否是正确的,也不确定执行此操作需要什么。

有人可以建议我在这种情况下需要做些什么,如何使UIColor可按照我需要的方式进行编码?

1 个答案:

答案 0 :(得分:1)

您为什么还希望UIColor符合Codable?它已经符合NSSecureCoding,因此默认情况下可序列化为Data

即使您实施了该程序,也可以对颜色进行编码

let encoded = UIColor.Words.adverb.encode()!

并解码

let color = UIColor.color(data: encoded)

尤其是在Core Data中,您可以使用计算的属性将受支持的类型转换为不受支持的类型,反之亦然。

我对核心数据的建议是将颜色另存为Int32(十六进制表示形式)或另存为(十六进制)String


这是我在Core Data中使用的实现,Core Data是将颜色转换为十六进制字符串的扩展

extension UIColor {

    private func float2String(_ float : CGFloat) -> String {
        return String(format:"%02X", Int(round(float * 255)))
    }

    var hex : String {
        var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0
        getRed(&red, green: &green, blue: &blue, alpha: nil)
        return "#" + float2String(red) + float2String(green) + float2String(blue)
    }

    convenience init(hex : String) {
        let hex = hex.hasPrefix("#") ? String(hex.dropFirst()) : hex
        if hex.count == 6, hex.range(of: "[^0-9A-Fa-f]", options: .regularExpression) == nil {
            let chars = Array(hex)
            let numbers = stride(from: 0, to: chars.count, by: 2).map() {
                CGFloat(strtoul(String(chars[$0 ..< min($0 + 2, chars.count)]), nil, 16))
            }
            self.init(red: numbers[0] / 255, green: numbers[1] / 255, blue: numbers[2] / 255, alpha: 1.0)
        } else {
            self.init(white: 1.0, alpha: 1.0)
        }
    }
}

NSManagedObject子类的相关部分

@NSManaged public var hexColor: String


var color : UIColor {
    get { return UIColor(hex: hexColor) }
    set { hexColor = newValue.hex }
}