Stefan Fletcher
Stefan Fletcher

Reputation: 47

How to change the colour of the previous view controller from the current view controller?

I am having a problem with changing the colour of a view controller. I want to tap a button on the current controller and it will change the background colour of the previous controller and save it

@IBAction func viewColourChange(_ sender: UIButton) {
        UIView.animate(withDuration: 0.5, animations:
            {self.viewColourChange.backgroundColor = #colorLiteral(red: 1, green: 0.9856258568, blue: 0.2624827082, alpha: 1)
        }, completion: nil)
        Haptic.impact(.medium).generate()
    }

I have it so when I click the button a specific UIView changes colour which is what I want but I also want it to change the colour of the previous controller background colour and save it

I think it has something to do with singleton or notifications but I am just getting so confused!

Upvotes: 0

Views: 225

Answers (2)

David Steppenbeck
David Steppenbeck

Reputation: 1084

An easy way to do this is with NotificationCenter. First, post a notification in your current view controller when you tap the button:

@IBAction func viewColourChange(_ sender: UIButton) {
    let newColor = #colorLiteral(red: 1, green: 0.9856258568, blue: 0.2624827082, alpha: 1)
    UIView.animate(withDuration: 0.5, animations: { self.viewColourChange.backgroundColor = newColor }, completion: nil)
    Haptic.impact(.medium).generate()
    NotificationCenter.default.post(name: .viewColorChanged, object: nil, userInfo: ["newColor" : newColor])
}

And add this extension somewhere in your code:

extension Notification.Name {
    static let viewColorChanged = Notification.Name("viewColorChanged")
}

Then add an observer for that notification in your previous view controller, for example:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(forName: .viewColorChanged, object: nil, queue: .main, using: { [weak self] notification in
            if let newColor = notification.userInfo?["newColor"] as? UIColor {
                self?.view.backgroundColor = newColor // or whichever view you want to update
            }
        }
    )
}

Edit: To save the new color, you can use UserDefaults:

extension UserDefaults {
    private struct SharedKeys {
        static let viewColor = "viewColor"
    }

    static var viewColor: UIColor? {
        get {
            if let components = standard.array(forKey: SharedKeys.viewColor) as? [Double], components.count == 4 {
                return UIColor(
                    red: CGFloat(components[0]),
                    green: CGFloat(components[1]),
                    blue: CGFloat(components[2]),
                    alpha: CGFloat(components[3])
                )
            }
            return nil
        }

        set {
            guard let components = newValue?.cgColor.components, components.count == 4 else {
                standard.setNilValueForKey(SharedKeys.viewColor)
                return
            }
            standard.set(components.map { Double($0) }, forKey: SharedKeys.viewColor)
        }
    }
}

Usage:

UserDefaults.viewColor = newColor // to save a color
UserDefaults.viewColor // to read a saved color

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100523

When you present/push the second vc , set a delegate like

let second = ///
second.delegate = self
present/push/segue

Then inside the second vc add the var

weak var delegate:FirstVC?

Then change it

delegate?.view.backgroundColor = ///

Upvotes: 5

Related Questions