Pregunta

¿Cuál es la mejor manera de ahorrar un UIColor en NSUserDefaults y luego recuperarlo a cabo?

¿Fue útil?

Solución

la respuesta aceptada , que va a terminar rápidamente con una gran cantidad de archivos y NSKeyed desarchiva todo su código . Una solución más limpia es extender UserDefaults. Esto es exactamente lo que las extensiones son para; UserDefaults probablemente no sabe nada de UIColor como es porque UIKit y la Fundación son diferentes marcos.

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

}

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

    }

}

Uso

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

Esto también se puede hacer en Objective-C con una categoría.

He añadido el archivo Swift como una esencia aquí .

Otros consejos

Una forma de hacerlo podría ser archivarlo (como con NSColor, aunque no he probado esto):

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

Y para recuperarla:

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

Tengo la respuesta por mí mismo

Guardar

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

Gracias por categoría UIColor de Erica . No me gusta mucho el ahorro de 4 flota en las preferencias, y sólo quería una sola entrada.

Así, utilizando la categoría UIColor de Erica, yo era capaz de convertir el RGB color a / desde un NSString que se pueden guardar en las preferencias.

// 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 extensión

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

Ejemplo Uso

let colorKey = "favoriteColor"

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

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


Esta respuesta se basa en una respuesta anterior . Se actualiza para Swift 3.

que necesitaba para almacenar matriz de objetos UIColor en la configuración de usuario. Idea, como se ha dicho en otras respuestas, es convertir a UIColor de datos y guardar los datos. He hecho la extensión de 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
   }
}

Uso:

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

    }
}

Swift

private let colorPickerKey = "ColorPickerKey"

var selectedColor: UIColor? {
    get {
        guard let colorData = UserDefaults.standard.object(forKey: colorPickerKey) as? Data,
            let color = NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor else { return nil }
        return color
    } set {
        guard let newValue = newValue else {
            UserDefaults.standard.removeObject(forKey: colorPickerKey)
            return
        }
        let colorData = NSKeyedArchiver.archivedData(withRootObject: newValue)
        UserDefaults.standard.set(colorData, forKey: colorPickerKey)
    }
}

Editar 2: Me parece haber encontrado la respuesta . Consulte el artículo por Erica Sadun en extender UIColor.

Editar no parece funcionar para un objeto de UIColor Este código. No sé por qué ...

Aquí hay un código para echar un vistazo a:

Almacenamiento de un objeto en NSUserDefaults:

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

Lectura de un objeto a partir de NSUserDefaults:

NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
UIColor *someColor = (UIColor *)[userDefaults objectForKey:@"myColor"];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top