I'm saving some colors picked with a colorPickerView in UserDefaults to display them in a collectionView.
My vc works like this:
- You press a cell in the collection view;
- The cell's index is collected in userdefaults;
- At the same time the colorPickerView is displayed;
- The user chooses a color, the picker is dismissed and the color is displayed in a collection view cell;
When I call the methods to dismiss the colorPickerView, I save the picked color with userDefaults and I refresh both the array containing my colors (yes I know it's not recommended but I haven't found a better way to do that yet) and the collection view which displays them. The problem is that after I refresh the array, everything in my view controller doesn't respond anymore to my commands (if I press on my collection view's cells they do nothing).
These are the extensions to save andd retrieve colors with userdefaults:
extension UserDefaults {
func setColor(color: UIColor?, forKey key: String) {
var colorData: NSData?
if let color = color {
do {
colorData = try NSKeyedArchiver.archivedData(withRootObject: color, requiringSecureCoding: false) as NSData?
set(colorData, forKey: key)
} catch let error {
print("error archiving color data", error)
}
}
}
func colorForKey(key: String) -> UIColor? {
var color: UIColor? = .white
if let colorData = data(forKey: key) {
do{
color = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: colorData)
} catch let error {
print("error unarchivig color data", error)
}
}
return color
}
}
This is how I declare my colors variable:
//Colors
var color1 : UIColor? = UserDefaults.standard.colorForKey(key: Ids.Keys.color1Key)
var color2 : UIColor? = UserDefaults.standard.colorForKey(key: Ids.Keys.color2Key)
var color3 : UIColor? = UserDefaults.standard.colorForKey(key: Ids.Keys.color3Key)
var color4 : UIColor? = UserDefaults.standard.colorForKey(key: Ids.Keys.color4Key)
var colorsArray: [UIColor] = []
This is the function I use every time I want the colorsArray to be refreshed:
func fillColorsArray(){
color1 = UserDefaults.standard.colorForKey(key: Ids.Keys.color1Key)
color2 = UserDefaults.standard.colorForKey(key: Ids.Keys.color2Key)
color3 = UserDefaults.standard.colorForKey(key: Ids.Keys.color3Key)
color4 = UserDefaults.standard.colorForKey(key: Ids.Keys.color4Key)
colorsArray = [color1!, color2!, color3!, color4!]
}
This is the function I call in my colorPickerViewControllerDidFinish:
func checkAndUpdateColor(viewController: UIColorPickerViewController){
passedCellIndex = UserDefaults.standard.integer(forKey: Ids.Keys.passedCellIndexKey)//Index of the tapped collection view cell
switch passedCellIndex {
case 0:
color1 = viewController.selectedColor
UserDefaults.standard.setColor(color: color1, forKey: Ids.Keys.color1Key)
break
case 1:
color2 = viewController.selectedColor
UserDefaults.standard.setColor(color: color2, forKey: Ids.Keys.color2Key)
break
case 2:
color3 = viewController.selectedColor
UserDefaults.standard.setColor(color: color3, forKey: Ids.Keys.color3Key)
break
case 3:
color4 = viewController.selectedColor
UserDefaults.standard.setColor(color: color4, forKey: Ids.Keys.color4Key)
break
default:
break
}
fillColorsArray()
collectionView.reloadData()
}
What causes the problem is the fillColorsArray() function: after calling that, when the picker is dismissed nothing in my view works. However it is the only way I have to display the picked color in my collection view. How can I prevent the fillColorsArray() function from blocking my whole view?
I fixed this by removing the
fillColorsArray()function from thecheckAndUpdateColor()function. I put it at the top of the collection view'scellForItemAtinstead so that it is called when thereloadDatafunction is called.