Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 核心数据模型:UIColor的属性类型_Iphone_Objective C_Cocoa Touch_Core Data - Fatal编程技术网

Iphone 核心数据模型:UIColor的属性类型

Iphone 核心数据模型:UIColor的属性类型,iphone,objective-c,cocoa-touch,core-data,Iphone,Objective C,Cocoa Touch,Core Data,我只是从核心数据开始,现在我正在构建我的数据模型。我的实体需要一个UIColor属性,但是属性的类型下拉列表中没有这个选项。我是否将其设置为未定义或什么 谢谢您可能想要的是一个可转换的属性。对《核心数据编程指南》中关于“”的部分进行另一次阅读。可转换属性在封面下是二进制数据属性,但核心数据将自动使用规范的NSValueTransformer为您序列化和取消序列化逻辑属性值。对于符合NSCoding的值,将使用NSKeyedUnarchiveFromDataTransformerName(默认的转

我只是从核心数据开始,现在我正在构建我的数据模型。我的实体需要一个UIColor属性,但是属性的类型下拉列表中没有这个选项。我是否将其设置为未定义或什么


谢谢

您可能想要的是一个可转换的属性。对《核心数据编程指南》中关于“”的部分进行另一次阅读。可转换属性在封面下是二进制数据属性,但核心数据将自动使用规范的
NSValueTransformer
为您序列化和取消序列化逻辑属性值。对于符合
NSCoding
的值,将使用
NSKeyedUnarchiveFromDataTransformerName
(默认的转换器)来实现


当然,对于SQLite后端,核心数据不能索引或查询此可转换值。

我将解释Dave Mark和Jeff LeMarche在更多iPhone 3开发中找到的明确答案:

通常我们可以将可转换属性的transformer类保留为默认的NSKeyedUnachiveFromData,但在这种情况下,我们不能这样做,因为
UIColor
不符合
NSCoding
并且不能使用
NSKeyedArchiver
存档。我们必须手动编写一个值转换器来处理转换

向实体添加一个属性,并将该属性称为“颜色”,或任意名称。将其类型设置为可转换。将其“值转换器名称”设置为UIColorRGBValueTransformer。请注意,数据模型编辑器不会验证值转换器名称:为了确保它是有效的类,请仔细键入

创建一个新文件,即
NSObject
的子类,并将其命名为UIColorRGBValueTransformer.m

单击UIColorRGBValueTransformer.h并将超类从NSObject更改为NSValueTransformer。另外,将
#import
更改为
#import
,因为
UIColor
UIKit
的一部分,而不是
Foundation

现在在uicolorGBvalueTransformer.m中,我们需要实现四种方法,允许我们的值转换器类将
UIColor
的实例转换为
NSData
,反之亦然。在UIColorRGBValueTransformer.m中包含以下代码:

现在,在另一个文件中,可以包含一行代码,如:

[self.managedObject setValue:color forKey:self.keyPath];

无需在文件中导入UIColorGBValueTransformer.h。

是否可以将UIColor作为字符串存储为十六进制(FFFFFF或其他web安全颜色),然后在读取颜色时,在使用名称ColorToDataTransformer将颜色属性指定为可转换后,可以将字符串转换为UIColor可以理解的格式。 我们可以简单地生成MangatedObjectSubclass并在其中编写转换器代码

//样本实体

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface SampleEntity : NSManagedObject
@property (nonatomic, retain) UIColor *color;
@end

@interface ColorToDataTransformer : NSValueTransformer
@end

这里是Swift版本的@RosePerrone answers。 我希望有帮助

class ColorToDataTransformer: ValueTransformer {

// Here we indicate that our converter supports two-way conversions.
// That is, we need  to convert UICOLOR to an instance of NSData and back from an instance of NSData to an instance of UIColor.
// Otherwise, we wouldn't be able to beth save and retrieve values from the persistent store.
override class func allowsReverseTransformation() -> Bool {
    return true
}

override class func transformedValueClass() -> AnyClass {
    return NSData.self
}

// Takes a UIColor, returns an NSData
override func transformedValue(_ value: Any?) -> Any? {
    guard let color = value as? UIColor else { return nil }

    guard let components: [CGFloat] = color.cgColor.components else { return nil }

    let colorAsString: String = String(format: "%f,%f,%f,%f", components[0], components[1], components[2], components[3])

    return colorAsString.data(using: .utf8)
}

// Takes an NSData, returns a UIColor
override func reverseTransformedValue(_ value: Any?) -> Any? {
    guard let data = value as? Data else { return nil }

    guard let colorAsString = String(data: data, encoding: .utf8) else { return nil }

    let componets: [String] = colorAsString.components(separatedBy: ",")

    var values: [Float] = []

    for component in componets {
        guard let value = Float(component) else { return nil }
        values.append(value)
    }

    let red: CGFloat = CGFloat(values[0])
    let green: CGFloat = CGFloat(values[1])
    let blue: CGFloat = CGFloat(values[2])
    let alpha: CGFloat = CGFloat(values[3])

   return UIColor(red: red, green: green, blue: blue, alpha: alpha)
}

}

这个答案太神奇了,我永远也想不到。一个小小的编辑,“AllowsReverseTransformation”和“TransformedValue”拼写错误,但修复只占所需6个字母中的2个。虽然这确实有效,但应该注意的是UIColor实际上符合NSCoding(与上面提到的相反),并且不需要特殊的转换器。
#import "SampleEntity.h"

@implementation SampleEntity

@dynamic color;

@end

@implementation ColorToDataTransformer

+ (BOOL)allowsReverseTransformation {
    return YES;
}

+ (Class)transformedValueClass {
    return [NSData class];
}


- (id)transformedValue:(id)value {
    UIColor *color = (UIColor *)value;
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:color];
    return data;
}

- (id)reverseTransformedValue:(id)value {
    NSData *data = (NSData *)value;
    UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    return color;
}

@end
class ColorToDataTransformer: ValueTransformer {

// Here we indicate that our converter supports two-way conversions.
// That is, we need  to convert UICOLOR to an instance of NSData and back from an instance of NSData to an instance of UIColor.
// Otherwise, we wouldn't be able to beth save and retrieve values from the persistent store.
override class func allowsReverseTransformation() -> Bool {
    return true
}

override class func transformedValueClass() -> AnyClass {
    return NSData.self
}

// Takes a UIColor, returns an NSData
override func transformedValue(_ value: Any?) -> Any? {
    guard let color = value as? UIColor else { return nil }

    guard let components: [CGFloat] = color.cgColor.components else { return nil }

    let colorAsString: String = String(format: "%f,%f,%f,%f", components[0], components[1], components[2], components[3])

    return colorAsString.data(using: .utf8)
}

// Takes an NSData, returns a UIColor
override func reverseTransformedValue(_ value: Any?) -> Any? {
    guard let data = value as? Data else { return nil }

    guard let colorAsString = String(data: data, encoding: .utf8) else { return nil }

    let componets: [String] = colorAsString.components(separatedBy: ",")

    var values: [Float] = []

    for component in componets {
        guard let value = Float(component) else { return nil }
        values.append(value)
    }

    let red: CGFloat = CGFloat(values[0])
    let green: CGFloat = CGFloat(values[1])
    let blue: CGFloat = CGFloat(values[2])
    let alpha: CGFloat = CGFloat(values[3])

   return UIColor(red: red, green: green, blue: blue, alpha: alpha)
}