Ahorro UIColor a y carga de NSUserDefaults
-
16-09-2019 - |
Pregunta
¿Cuál es la mejor manera de ahorrar un UIColor
en NSUserDefaults
y luego recuperarlo a cabo?
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"];