将UIColor存储在CoreData中

时间:2015-05-25 09:18:33

标签: swift core-data nsdata uicolor transformable

如何在 64位中存储 UIColor in CoreData 而不会丢失? 在32位上返回正确的UIColor。

CoreData设置

  • 属性类型:可转换
  • NSManagedObject子类属性: @NSManaged var color:UIColor?

存储颜色值之前

color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)

输出,例如64位红色:

0.20000000000000018  

32位输出红色

0.199999928

从CoreData检索颜色后

color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)

输出,例如64位红色:

0.20000000298023224 

在32位输出红色:

0.199999928

结果问题

使用==的颜色比较在64位上失败,因为值略有不同。在32位上一切都很好,颜色比较成功。

2 个答案:

答案 0 :(得分:2)

NSKeyedArchiver.archivedDataWithRootObject(color)分配给数据变量,并将其保存到Core Data存储中。

要读取数据,只需将NSKeyedUnarchiver.unarchiveObjectWithData(colorData)指定给颜色变量。

如果你想知道如何比较浮点数,你总是可以参考this

答案 1 :(得分:1)

这解决了我的问题:

  1. 将CoreData属性名称设置为我的自定义NSValueTransformer子类:MQColorTransformer

  2. 实现了以下NSValueTransformer子类(它也将UIColor转换为NSData,如 Schemetrical 建议,但它的优点是我仍然可以将UIColor分配给我的color属性并且NSValueTransformer需要注意在场景背后的转变):

  3. NSValueTransformer子类

    import Foundation
    import UIKit
    
    @objc(MQColorTransformer) class MQColorTransformer: NSValueTransformer {
    
      override class func transformedValueClass() -> AnyClass{
          return NSData.classForCoder()
      }
    
      override func transformedValue(value: AnyObject!) -> AnyObject {
    
          // Transform UIColor to NSData
          let color = value as! UIColor
    
          var red: CGFloat = 0
          var green: CGFloat = 0
          var blue: CGFloat = 0
          var alpha: CGFloat = 0
          color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
    
          var components:[CGFloat] = [red, green, blue, alpha]
          let dataFromColors = NSData(bytes: components,
              length: sizeofValue(components)*components.count)
    
          return dataFromColors
    
      }
    
      override func reverseTransformedValue(value: AnyObject!) -> AnyObject {
    
          // Transform NSData to UIColor
          let data = value  as! NSData
          var components = [CGFloat](count: 4, repeatedValue:0)
          var length=sizeofValue(components)
    
          data.getBytes(&components, length: length * components.count)
          let color = UIColor(red: components[0],
              green: components[1],
              blue: components[2],
              alpha: components[3])
    
          return color
      }
    }