5

当我需要将颜色保存到核心数据时,我只需使用 NSKeyedArchiever,然后在需要加载实体时取消归档颜色。但是,当我尝试序列化核心数据实体时,该过程会失败,因为它不知道如何将密钥归档的 NSData 转换为字符串。

将 UIColor 转换为字符串表示以在 JSON 文件中发送的最佳方法是什么?一种解决方案是将 r,g,b,a 值存储为浮点数。一种解决方案是将其保存为十六进制字符串。这两者似乎都使色彩恢复的过程复杂化

我错过了什么吗?有没有更简单的方法在 JSON 中序列化 UIColor?

4

5 回答 5

5

那个怎么样:

NSDictionary *colorData = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:100.f], @"Red",
                               [NSNumber numberWithFloat:24.f], @"Green",
                               [NSNumber numberWithFloat:23.f], @"Blue",
                               [NSNumber numberWithFloat:1.f], @"Alpha", nil];

NSDictionary *color = [NSDictionary dictionaryWithObject:colorData forKey:@"Color"];

结果是这样的:

{"Color":{"Green":24,"Alpha":1,"Blue":23,"Red":100}}

您可以轻松地创建一个方法,将UIColor其作为参数并返回一个可以直接序列化的 NSDictionary。逆过程是一样的。

于 2012-05-20T17:33:54.160 回答
2

由于在 JSON 中放置一个(更不用说通用“颜色”)没有定义的标准,UIColor你将不得不自己动手。

我建议最好的方法是有一个类别,UIColor它为您提供 RGB 颜色空间中颜色的标准十六进制代码,并且还接受这样的十六进制代码并吐出 s UIColor。然后以 JSON 格式传输该十六进制代码。

我知道这可能看起来有点矫枉过正,但它是迄今为止最便携和最紧凑的解决方案。

UIColor可以在我的MJGFoundationUIColor类别中找到hex to 方法的示例。一个类似的从UIColor到十六进制值不会太难写,但要知道必须首先在 RGBA 颜色空间中获取它。

于 2012-05-20T17:35:50.540 回答
2

这取决于颜色的“私有”格式的自由度。有些颜色对被要求输入 RGBA 反应不佳(因此这些get...方法为什么返回 a BOOL——它们并不总是成功),所以这个实现包括颜色类型和值。

@implementation UIColor (JSON)

- (NSString *)json_stringValue
{
    CGFloat r, g, b, a, h, s, w;
    if ([self getRed:&r green:&g blue:&b alpha:&a]) 
        return [NSString stringWithFormat:@"rgba:%f,%f,%f,%f", r,g,b,a];
    else if ([self getHue:&h saturation:&s brightness:&b alpha:&a])
        return [NSString stringWithFormat:@"hsba:%f,%f,%f,%f", h,s,b,a];
    else if ([self getWhite:&w alpha:&a]) 
        return [NSString stringWithFormat:@"wa:%f,%f", w, a];

    NSLog(@"WARNING: unable to serialize color %@", self);
    return nil;
}

@end

@implementation NSString (JSON)

- (UIColor *)json_color
{
    NSArray *comps = [self componentsSeparatedByString:@":"];
    NSArray *colors = [comps[1] componentsSeparatedByString:@","];
    NSUInteger count = colors.count;
    CGFloat values[4] = {0,0,0,0};
    for (NSUInteger i = 0; i < count; i++) values[i] = [colors[i] floatValue];

    if ([comps[0] isEqualToString:@"rgba"]) 
        return [UIColor colorWithRed:values[0] green:values[1] blue:values[2] alpha:values[3]];
    else if ([comps[0] isEqualToString:@"hsba"])
        return [UIColor colorWithHue:values[0] saturation:values[1] brightness:values[2] alpha:values[3]];
    else if ([comps[0] isEqualToString:@"wa"])
        return [UIColor colorWithWhite:values[0] alpha:values[1]];

    NSLog(@"WARNING: unable to deserialize color %@", self);
    return nil;
}

@end
于 2015-03-31T06:13:14.060 回答
1

我发现的解决方案是从 UIColor 创建 CIColor 然后转换回来:

转换为字符串:

CIColor(color: UIColor.blue).stringRepresentation

转换为颜色:

UIColor(ciColor: CIColor(string: databaseColorString))
于 2017-02-06T05:54:32.553 回答
0

结合这两个答案,结果如下:

保存:

#import "UIColor-HSVAdditions.h"
#import "JSONKit.h"

UIColor* color = textView.textColor;
            NSDictionary *colorData = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:color.hue], @"Hue",
                                       [NSNumber numberWithFloat:color.saturation], @"Saturation",
                                       [NSNumber numberWithFloat:color.brightness], @"Brightness",
                                       [NSNumber numberWithFloat:color.alpha], @"Alpha", nil];

            NSString* jsonString = [colorData JSONString];

装载:

 NSDictionary* dictionary = [coreDataEntity.fontColor objectFromJSONString];

                    NSNumber* hue =[dictionary objectForKey:kHueKey];
                    NSNumber* saturation =[dictionary objectForKey:kSaturationKey];
                    NSNumber* brightness =[dictionary objectForKey:kBrightnessKey];
                    NSNumber* alpha =[dictionary objectForKey:kAlphaKey];

                    UIColor* color = [UIColor colorWithHue:hue.floatValue saturation:saturation.floatValue brightness:brightness.floatValue alpha:alpha.floatValue];

                    textView.textColor = color;
于 2012-05-21T12:14:54.130 回答