Сохранение UIColor и загрузка из NSUserDefaults

какой самый простой способ сохранить UIColor на NSUserDefaults а потом вытащить обратно?

7 ответов


С принято отвечать, вы быстро закончите с большим количеством архивов NSKeyed & unarchives по всему вашему коду. Чистое решение продлить 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)
    }

}

использование

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

Это также можно сделать в Objective-C с категории.

Я добавлен файл Swift как gist здесь.


один из способов сделать это может быть архивировать его (например, с NSColor, хотя я не тестировал это):

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

и чтобы вернуть его:

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

Я получил ответ сам

сохранить

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

загрузить

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

спасибо категория UIColor Эрики. Мне не очень понравилось сохранение 4 поплавков в настройках, и просто хотелось одну запись.

Итак, используя Эрику 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];
}

Swift 3,UserDefaults расширение

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

Пример Использования

let colorKey = "favoriteColor"

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

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


Этот ответ основан на предыдущий ответ. Он обновлен для Swift 3.


мне нужно было сохранить массив 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
   }
}

использование:

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

    }
}

Edit 2: кажется, я нашел ответ. Ознакомьтесь со статьей Эрики Садун о расширении UIColor.

Edit: этот код не работает для объекта UIColor. Не знаю почему...

вот некоторый код, чтобы взглянуть на:

сохранение объекта в NSUserDefaults:

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

чтение объекта из NSUserDefaults:

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