marco
marco

Reputation: 676

User defaults Only Working On Restart

I am trying to implement a light and dark mode in my application. In the settingsViewController I have these lines of code:

//Sets user default for colour
let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

//UISegment control for user to pick colour
@IBOutlet var colourSegment: UISegmentedControl!

//Updates lightMode based on user selection
@IBAction func didChangeColours(_ sender: Any) {

    if colourSegment.selectedSegmentIndex == 0 {
        UserDefaults.standard.set(true, forKey: "lightMode")
    } else if colourSegment.selectedSegmentIndex == 1 {
        UserDefaults.standard.set(false, forKey: "lightMode")
    }

}

In my entryViewController, in my viewDidLoad, I have:

let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

if lightMode == false {
    Colours.darkMode()
}

customisations()

The issue that I'm running into is that for some reason, my application is only changing it's colour scheme after I restart it. That is, if the user selects the darkIndex of the colourSegment, the application only updates the colour after I restart. I am wondering what is the solution for this.

Upvotes: 1

Views: 1070

Answers (3)

Paulw11
Paulw11

Reputation: 114773

I am assuming that you are returning to your entryViewController from your settingsViewController; Since you are returning to an existing view controller instance, the code in viewDidLoad is not executed when you return.

Move the code to viewWillAppear; This way your code will execute prior to the view controller appearing even when you return to the existing instance:

func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

    if lightMode == false {
        Colours.darkMode()
    }
}

Upvotes: 0

Kapil G
Kapil G

Reputation: 4141

The problem is in the line -

//Sets user default for colour
let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

this line is not for setting the Userdefaults but instead it gets the UserDefaults. Since you use it before setting the default Value, it doesn't reflect the right segmented choice. So your setting part is correct and you should fetch the value only after you have set it.

Also in your entryViewController, instead of using it from settingsVC, do below -

//get from UserDefaults
let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

//Compare the previous fetched value
if lightMode == false {
    Colours.darkMode()
}

//This function sets the colour for the elements
colours()

Upvotes: 2

Tj3n
Tj3n

Reputation: 9923

Because you are assigning the lightMode value ONLY 1 time during init, you don't reflect the changes to the variable, so it will always be that value

To always get the lastest value, use this:

let lightMode: Bool {
   get {
       return UserDefaults.standard.bool(forKey: "lightMode")
   }
}

Also, you should call the color change immediatelly after change the value

Upvotes: 0

Related Questions