swift - 使 UIColor Codable - 符合协议(protocol) 'Encodable'

标签 swift encoding uicolor

我在从 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 没有被编码(?),尽管它似乎确实将一些“blob”加载到数据库中。

如果我听从 Make UIColor Codable 的建议, 和类似的,但我不断收到错误。

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

我想我需要使我的结构 Words: Codable,但我不确定这是否属实,也不确定这样做需要什么。

有人可以告诉我在这种情况下需要做什么如何使 UIColor 以我需要的方式进行编码吗?

最佳答案

为什么要 UIColor 额外符合 Codable?它已经符合 NSSecureCoding,因此默认情况下可序列化为 Data

即使通过您的实现,您也可以对颜色进行编码

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

解码

let color = UIColor.color(data: encoded)

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

我对 Core Data 的建议是将颜色保存为 Int32(十六进制表示)或(十六进制)String


这是我在 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 }
}

关于swift - 使 UIColor Codable - 符合协议(protocol) 'Encodable',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56902318/

相关文章:

swift - 转换分段控件中的特定段

ios - 在 iOS 13 中获取 UIScrollView 的完整屏幕截图

python - 非 ASCII 字符的语法错误

json - 使用 Postman 编码变量

objective-c - 设置自定义 tableviewCell 的背景

ios - 使用 NSString 为标签设置颜色

ios - UICollectionView - 如何在同一部分显示不同高度的项目?

ios - SwiftUI - 修复在没有列表的情况下使用可搜索时的动画跳转

java - Tomcat Servlet 文件上传和 UTF-8

ios - 带有图像的 UIColor 颜色在 IOS 7 下不起作用