Модель данных Core Data: тип атрибута для UIColor - PullRequest
6 голосов
/ 21 февраля 2010

Я только начинаю с Core Data и сейчас строю свою модель данных. Мне нужен атрибут UIColor для моей сущности, но раскрывающийся список типов для атрибута не имеет опции для этого. Я должен установить его на неопределенный или как?

Спасибо

Ответы [ 5 ]

20 голосов
/ 03 июля 2010

Я перефразирую определенный ответ, который я нашел в Подробнее о разработке iPhone 3 Дэйва Марка и Джеффа ЛеМарша:

Обычно мы можем оставить класс преобразователя трансформируемого атрибута по умолчанию, NSKeyedUnarchiveFromData , и это будет сделано, но в этом случае мы не можем, потому что UIColor этого не делает соответствует NSCoding и не может быть заархивирован с помощью NSKeyedArchiver. Мы должны вручную написать преобразователь значения для обработки преобразования.

Добавьте атрибут к вашей сущности и назовите атрибут «цвет», или любое другое имя, которое вы пожелаете. Установите его тип Transformable . Установите для его «Имя преобразователя значения» значение UIColorRGBValueTransformer . Обратите внимание, что редактор модели данных не проверяет Value Transformer Name: , чтобы убедиться, что это допустимый класс, поэтому набирайте внимательно.

Создайте новый файл, подкласс NSObject и назовите его UIColorRGBValueTransformer.m .

Нажмите UIColorRGBValueTransformer.h и измените суперкласс с NSObject на NSValueTransformer. Кроме того, измените #import <Foundation/Foundation.h> на #import <UIKit/UIKit.h>, поскольку UIColor является частью UIKit, а не Foundation.

Теперь в UIColorRGBValueTransformer.m нам нужно реализовать четыре метода, которые позволяют нашему классу преобразователя значений преобразовывать экземпляры UIColor в NSData и наоборот. Включите следующий код в UIColorRGBValueTransformer.m :

#import "UIColorRGBValueTransformer.h"

@implementation UIColorRGBValueTransformer

// Here we override the method that returns the class of objects that this transformer can convert.
+ (Class)transformedValueClass {
    return [NSData class];
}

// 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.
+ (BOOL)allowsReversTransformation {
    return YES;
}

// Takes a UIColor, returns an NSData
- (id)transfomedValue:(id)value {
    UIColor *color = value;
    const CGFloat *components = CGColorGetComponents(color.CGColor);
    NSString *colorAsString = [NSString stringWithFormat:@"%f,%f,%f,%f", components[0], components[1], components[2], components[3]];
    return [colorAsString dataUsingEncoding:NSUTF8StringEncoding];
}

// Takes an NSData, returns a UIColor
- (id)reverseTransformedValue:(id)value {
    NSString *colorAsString = [[[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding] autorelease];
    NSArray *components = [colorAsString componentsSeparatedByString:@","];
    CGFloat r = [[components objectAtIndex:0] floatValue];
    CGFloat g = [[components objectAtIndex:1] floatValue];
    CGFloat b = [[components objectAtIndex:2] floatValue];
    CGFloat a = [[components objectAtIndex:3] floatValue];
    return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

@end

Теперь в другом файле вы можете включить строку кода, например:

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

без необходимости импортировать UIColorRGBValueTransformer.h в файл.

16 голосов
/ 21 февраля 2010

То, что вы, вероятно, хотите, это трансформируемый атрибут. Прочитайте раздел « Нестандартные постоянные атрибуты » в Руководстве по программированию основных данных. Преобразуемый атрибут - это под двоичными данными атрибут двоичных данных, но Core Data автоматически использует NSValueTransformer вашей спецификации для сериализации и десериализации значения логического атрибута. Для значений, которые NSCoding соответствуют, NSKeyedUnarchiveFromDataTransformerName (который является преобразователем по умолчанию) сделает свое дело.

Конечно, Core Data не может индексировать или, для серверной части SQLite, запрашивать это преобразовываемое значение.

3 голосов
/ 04 августа 2013

После укажите цветовой атрибут как трансформируемый с именем ColorToDataTransformer.Мы можем просто сгенерировать MangatedObjectSubclass и написать внутри него код преобразователя

// SampleEntity.h

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

@interface ColorToDataTransformer : NSValueTransformer
@end

// SampleEntity.m

#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
3 голосов
/ 25 сентября 2010

Можно ли сохранить UIColor в виде строки как HEX (FFFFFF или другие веб-безопасные цвета), а затем, когда вы приходите для чтения цвета, вы конвертируете строку в формат, понятный UIColor?*

0 голосов
/ 28 июля 2018

Вот это версия ответов @RosePerrone Свифта. Надеюсь, это поможет.

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)
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...