将UIColor保存到NSUserDefaults并从NSUserDefaults加载

Unr*_*ity 52 cocoa-touch objective-c nsuserdefaults uicolor

什么是保存最简单的方法UIColor进入NSUserDefaults,然后拿回来了呢?

Wev*_*vah 133

这样做的一种方法可能是归档它(就像使用NSColor,虽然我没有测试过这个):

NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];
Run Code Online (Sandbox Code Playgroud)

并把它拿回来:

NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
Run Code Online (Sandbox Code Playgroud)

  • UIColor实现了NSCoding协议,因此归档将起作用. (3认同)
  • 这种方式还可以保存与颜色相关的颜色配置文件.如果这对你不重要,当然. (3认同)
  • 在Swift中:`var colorData:NSData = NSKeyedArchiver.archivedDataWithRootObject(color); defaults.setObject(colorData,forKey:"BackgroundColor");` (2认同)

And*_*rew 61

通过接受的答案,您将很快在代码中获得大量NSKeyed归档和解压缩.更清洁的解决方案是扩展UserDefaults.这正是扩展的目的; UserDefaults可能不知道UIColor,因为UIKit和Foundation是不同的框架.

迅速

extension UserDefaults {

    func color(forKey key: String) -> UIColor? {
        var color: UIColor?
        if let colorData = data(forKey: key) {
            color = NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor
        }
        return color
    }

    func set(_ value: UIColor?, forKey key: String) {
        var colorData: Data?
        if let color = value {
            colorData = NSKeyedArchiver.archivedData(withRootObject: color)
        }
        set(colorData, forKey: key)
    }

}
Run Code Online (Sandbox Code Playgroud)

Swift 4.2

extension UserDefaults {

    func color(forKey key: String) -> UIColor? {

        guard let colorData = data(forKey: key) else { return nil }

        do {
            return try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: colorData)
        } catch let error {
            print("color error \(error.localizedDescription)")
            return nil
        }

    }

    func set(_ value: UIColor?, forKey key: String) {

        guard let color = value else { return }
        do {
            let data = try NSKeyedArchiver.archivedData(withRootObject: color, requiringSecureCoding: false)
            set(data, forKey: key)
        } catch let error {
            print("error color key data not saved \(error.localizedDescription)")
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

用法

UserDefaults.standard.set(UIColor.white, forKey: "white")
let whiteColor = UserDefaults.standard.color(forKey: "white")
Run Code Online (Sandbox Code Playgroud)

这也可以在具有类别的Objective-C中完成.

我已经添加了斯威夫特文件作为依据这里.

  • 您也可以在Objective-C中使用类别执行此操作. (2认同)
  • Swift 3版本:https://gist.github.com/D-32/d30482e7fa10b6158e69610335052752 (2认同)

Unr*_*ity 7

我自己得到了答案

保存

const CGFloat  *components = CGColorGetComponents(pColor.CGColor);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setFloat:components[0]  forKey:@"cr"];
[prefs setFloat:components[1]  forKey:@"cg"];
[prefs setFloat:components[2]  forKey:@"cb"];
[prefs setFloat:components[3]  forKey:@"ca"];
Run Code Online (Sandbox Code Playgroud)

加载

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
UIColor* tColor = [UIColor colorWithRed:[prefs floatForKey:@"cr"] green:[prefs floatForKey:@"cg"] blue:[prefs floatForKey:@"cb"] alpha:[prefs floatForKey:@"ca"]];
Run Code Online (Sandbox Code Playgroud)

  • 可能出现的唯一问题是底层CGColor不在RGB色彩空间中.如果您确定它将是RGB,这可能是比档案更好的选择. (5认同)

lif*_*joy 5

感谢Erica的UIColor类别.我不喜欢在首选项中保存4个浮点数,只想要一个条目.

因此,使用Erica的UIColor类别,我能够将RGB颜色转换为NSString可以保存在首选项中的颜色.

// Save a color
NSString *theColorStr = [self.artistColor stringFromColor];
[[NSUserDefaults standardUserDefaults] setObject:theColorStr forKey:@"myColor"];

// Read a color
NSString *theColorStr = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
if ([theColorStr length] > 0) {
    self.myColor = [UIColor colorWithString:theColorStr];
} else {
    self.myColor = [UIColor colorWithRed:88.0/255.0 green:151.0/255.0 blue:237.0/255.0 alpha:1.0];
}
Run Code Online (Sandbox Code Playgroud)

  • 查看`[NSUserDefaults registerDefaults:]`来设置一个默认值(这样你就可以在读取值时避免使用if/else). (6认同)