保存UIColor到NSUserDefaults中进行加载

时间:2022-08-24 16:24:16

What's the easiest way to save a UIColor into NSUserDefaults and then get it back out?

将UIColor保存到NSUserDefaults中并将其取出的最简单方法是什么?

7 个解决方案

#1


53  

With the accepted answer, you'll quickly end up with a lot of NSKeyed archives & unarchives all over your code. A cleaner solution is to extend UserDefaults. This is exactly what extensions are for; UserDefaults probably doesn't know about UIColor as it is because UIKit and Foundation are different frameworks.

有了公认的答案,您将很快得到大量的非定向归档和反归档文件。一个更简洁的解决方案是扩展UserDefaults。这就是扩展的意义;UserDefaults可能不知道UIColor因为UIKit和Foundation是不同的框架。

Swift

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

}

Usage

UserDefaults.standard.set(UIColor.white, forKey: "white")
let whiteColor = UserDefaults.standard.color(forKey: "white")

This can also be done in Objective-C with a category.

这也可以在Objective-C中通过一个类别来实现。

I've added the Swift file as a gist here.

我在这里添加了Swift文件作为要点。

#2


128  

One way of doing it might be to archive it (like with NSColor, though I haven't tested this):

一种方法可能是将它存档(比如NSColor,尽管我还没有对此进行测试):

NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];

And to get it back:

为了找回它:

NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];

#3


7  

I've got the answer by myself

我自己有答案。

Save

保存

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"];

Load

负载

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
UIColor* tColor = [UIColor colorWithRed:[prefs floatForKey:@"cr"] green:[prefs floatForKey:@"cg"] blue:[prefs floatForKey:@"cb"] alpha:[prefs floatForKey:@"ca"]];

#4


5  

Thanks for Erica's UIColor category. I did not really like saving 4 floats in the preferences, and just wanted a single entry.

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

So using Erica's UIColor category, I was able to convert the RGB color to/from an NSString which can be saved in the preferences.

因此,使用Erica的UIColor类别,我能够将RGB颜色转换为/从NSString中转换,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];
}

#5


2  

Swift 3, UserDefaults Extension

extension UserDefaults {

    internal func color(forKey key: String) -> UIColor? {
        guard let colorData = data(forKey: key) else {
            return nil
        }

        return NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor
    }

    internal func setColor(_ color: UIColor?, forKey key: String) {
        let colorData: Data?
        if let color = color {
            colorData = NSKeyedArchiver.archivedData(withRootObject: color)
        }
        else {
            colorData = nil
        }

        set(colorData, forKey: key)
    }
}

Example Use

let colorKey = "favoriteColor"

UserDefaults.standard.setColor(UIColor.red, forKey: colorKey)
let favoriteColor = UserDefaults.standard.color(forKey: colorKey)

print("favoriteColor is red: '\(favoriteColor == UIColor.red)'")


This answer is based on a previous answer. It is updated for Swift 3.

这个答案是基于之前的答案。更新为Swift 3。

#6


0  

I needed to store array of UIColor objects in User Defaults. Idea, as stated in other answers, is to convert UIColor to Data and save that data. I've made extension on UIColor:

我需要以用户默认值存储UIColor对象的数组。如其他答案所述,想法是将UIColor转换为数据并保存该数据。我在UIColor上做了延伸:

extension UIColor {
   func data() -> Data {
      return NSKeyedArchiver.archivedData(withRootObject: self)
   }
   class func color(withData data: Data) -> UIColor? {
      return NSKeyedUnarchiver.unarchiveObject(with: data) as? UIColor
   }
}

Usage:

用法:

fileprivate var savedColors: [UIColor]? {
    get {
        if let colorDataArray = UserDefaults.standard.array(forKey: Constants.savedColorsKey) as? [Data] {
            return colorDataArray.map { UIColor.color(withData: $0)! }
        }
        return nil
    }
    set {
        if let colorDataArray = newValue?.map({ $0.data() }) {
            UserDefaults.standard.set(colorDataArray, forKey: Constants.savedColorsKey)
        }

    }
}

#7


-4  

Edit 2: I seem to have found the answer. Check out the article by Erica Sadun on extending UIColor.

编辑2:我似乎找到了答案。看看Erica Sadun关于扩展UIColor的文章。

Edit: This code does not seem to work for a UIColor Object. Not sure why...

编辑:这段代码似乎不适用于UIColor对象。不知道为什么……

Here is some code to take a look at:

这里有一些代码可以参考:

Saving an object into NSUserDefaults:

将对象保存到NSUserDefaults:

 NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:someColorObject forKey:@"myColor"];

Reading an object from NSUserDefaults:

从NSUserDefaults中读取对象:

NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
UIColor *someColor = (UIColor *)[userDefaults objectForKey:@"myColor"];

#1


53  

With the accepted answer, you'll quickly end up with a lot of NSKeyed archives & unarchives all over your code. A cleaner solution is to extend UserDefaults. This is exactly what extensions are for; UserDefaults probably doesn't know about UIColor as it is because UIKit and Foundation are different frameworks.

有了公认的答案,您将很快得到大量的非定向归档和反归档文件。一个更简洁的解决方案是扩展UserDefaults。这就是扩展的意义;UserDefaults可能不知道UIColor因为UIKit和Foundation是不同的框架。

Swift

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

}

Usage

UserDefaults.standard.set(UIColor.white, forKey: "white")
let whiteColor = UserDefaults.standard.color(forKey: "white")

This can also be done in Objective-C with a category.

这也可以在Objective-C中通过一个类别来实现。

I've added the Swift file as a gist here.

我在这里添加了Swift文件作为要点。

#2


128  

One way of doing it might be to archive it (like with NSColor, though I haven't tested this):

一种方法可能是将它存档(比如NSColor,尽管我还没有对此进行测试):

NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];

And to get it back:

为了找回它:

NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];

#3


7  

I've got the answer by myself

我自己有答案。

Save

保存

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"];

Load

负载

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
UIColor* tColor = [UIColor colorWithRed:[prefs floatForKey:@"cr"] green:[prefs floatForKey:@"cg"] blue:[prefs floatForKey:@"cb"] alpha:[prefs floatForKey:@"ca"]];

#4


5  

Thanks for Erica's UIColor category. I did not really like saving 4 floats in the preferences, and just wanted a single entry.

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

So using Erica's UIColor category, I was able to convert the RGB color to/from an NSString which can be saved in the preferences.

因此,使用Erica的UIColor类别,我能够将RGB颜色转换为/从NSString中转换,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];
}

#5


2  

Swift 3, UserDefaults Extension

extension UserDefaults {

    internal func color(forKey key: String) -> UIColor? {
        guard let colorData = data(forKey: key) else {
            return nil
        }

        return NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor
    }

    internal func setColor(_ color: UIColor?, forKey key: String) {
        let colorData: Data?
        if let color = color {
            colorData = NSKeyedArchiver.archivedData(withRootObject: color)
        }
        else {
            colorData = nil
        }

        set(colorData, forKey: key)
    }
}

Example Use

let colorKey = "favoriteColor"

UserDefaults.standard.setColor(UIColor.red, forKey: colorKey)
let favoriteColor = UserDefaults.standard.color(forKey: colorKey)

print("favoriteColor is red: '\(favoriteColor == UIColor.red)'")


This answer is based on a previous answer. It is updated for Swift 3.

这个答案是基于之前的答案。更新为Swift 3。

#6


0  

I needed to store array of UIColor objects in User Defaults. Idea, as stated in other answers, is to convert UIColor to Data and save that data. I've made extension on UIColor:

我需要以用户默认值存储UIColor对象的数组。如其他答案所述,想法是将UIColor转换为数据并保存该数据。我在UIColor上做了延伸:

extension UIColor {
   func data() -> Data {
      return NSKeyedArchiver.archivedData(withRootObject: self)
   }
   class func color(withData data: Data) -> UIColor? {
      return NSKeyedUnarchiver.unarchiveObject(with: data) as? UIColor
   }
}

Usage:

用法:

fileprivate var savedColors: [UIColor]? {
    get {
        if let colorDataArray = UserDefaults.standard.array(forKey: Constants.savedColorsKey) as? [Data] {
            return colorDataArray.map { UIColor.color(withData: $0)! }
        }
        return nil
    }
    set {
        if let colorDataArray = newValue?.map({ $0.data() }) {
            UserDefaults.standard.set(colorDataArray, forKey: Constants.savedColorsKey)
        }

    }
}

#7


-4  

Edit 2: I seem to have found the answer. Check out the article by Erica Sadun on extending UIColor.

编辑2:我似乎找到了答案。看看Erica Sadun关于扩展UIColor的文章。

Edit: This code does not seem to work for a UIColor Object. Not sure why...

编辑:这段代码似乎不适用于UIColor对象。不知道为什么……

Here is some code to take a look at:

这里有一些代码可以参考:

Saving an object into NSUserDefaults:

将对象保存到NSUserDefaults:

 NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:someColorObject forKey:@"myColor"];

Reading an object from NSUserDefaults:

从NSUserDefaults中读取对象:

NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
UIColor *someColor = (UIColor *)[userDefaults objectForKey:@"myColor"];