How to save the state of an UISwitch in SWIFT 4?

Viewed 7993

I would like to save the State of an UISwitch after to change between View Controllers. Any help would be greatly appreciated!

I have a first View Controller with an UISwitch, to control the music in the background in different View Controllers:

@IBOutlet weak var SwitchMusic: UISwitch!
        let defaults = UserDefaults.standard
        var switchON : Bool = false

@IBAction func checkState(_ sender: UISwitch) {
        if (sender.isOn == true)
        {
            switchON = true
            defaults.set(switchON, forKey: "switchON")
            MusicHelper.sharedHelper.playBackgroundMusic()
        }
        if (sender.isOn == false)
        {
            switchON = false
            defaults.set(switchON, forKey: "switchON")
            MusicHelper.sharedHelper.stopBackgroundMusic()
        }
     }

And a Second View Controller to load or no the music in the background if the switch is On or Off:

override func viewDidLoad() {
        super.viewDidLoad()

        if defaults.value(forKey: "switchON") != nil{
            let switchON: Bool = defaults.value(forKey: "switchON")  as! Bool
            if switchON == true{
                MusicHelper.sharedHelper.playBackgroundMusic()
            }
            else if switchON == false{
                MusicHelper.sharedHelper.stopBackgroundMusic()
            }
        }
    }

Also I have a class with the music:

class MusicHelper {

    let defaults = UserDefaults.standard

    static let sharedHelper = MusicHelper()

    var musicBackgroundIntro:AVAudioPlayer = AVAudioPlayer()
    func playBackgroundMusic() {
        do {
            let audioPath = Bundle.main.path(forResource: "Music", ofType: "mp3")
            try musicBackgroundIntro = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL)
            musicBackgroundIntro.numberOfLoops = -1
            musicBackgroundIntro.prepareToPlay()
            musicBackgroundIntro.play()
        } catch {
            print("Cannot play the file")
        }
    }
    func stopBackgroundMusic() {
        musicBackgroundIntro.stop()
    }

}

Now it is working perfectly the music in the background between View Controllers, and it is possible to turn off and on... but unfortunately do not save the current state of the UISwitch, and always when I enter in the First View Controller the state of the Switch is On.

Also any idea that how will be possible to apply in a Slider too?

Any help would be greatly appreciated!

Thanks

4 Answers

The easiest way for you would be to create a static var isSwitchOn: Bool = false

This state will be preserved between back and forth transitions.

You should reflect the state, if music is playing...

class MusicHelper {
    public isPlaying: Bool {
       get {
           return musicBackgroundIntro.isPlaying
       }
    }

 // your stuff here..

}

That way in other view controllers:

SwitchMusic.isOn = MusicHelper.sharedHelper.isPlaying

If you need other view controllers to update in response to this, you can add a delegate event (aka observer) if necessary.

You can give the switch a default value when it's created in viewcontroller1.

Assign the (default.value(forKey:"switchOn") as! Bool ) ?? false to that switch.

Try something like that: Use the UISwitch as an @IBOutlet.

@IBOutlet weak var checkState: UISwitch!

override func viewDidLoad() {
      super.viewDidLoad()
   self.checkState.addTarget(self, action: #selector(action(sender:)), for: .valueChanged)
}

// Save state
func action(sender: UISwitch) {

  let userDefaults = UserDefaults.standard
  userDefaults.set(sender.isOn, forKey:"identifier")

}

// Retrieve state
override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)

  let userDefaults = UserDefaults.standard.bool(forKey: "identifier")
  self.checkState.setOn(userDefaults, animated: false)

}
Related