Search code examples
iosswiftuserdefaultsuicolorpickerviewcontroller

Whole view blocks after dismissing color picker veiw


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?


Solution

  • I fixed this by removing the fillColorsArray() function from the checkAndUpdateColor() function. I put it at the top of the collection view's cellForItemAt instead so that it is called when the reloadData function is called.