Receiving a notification without loading the view

2019-09-06 05:31发布

As I explained in this question, I'm trying to pass data from a UISwitch in a TableView to another ViewController. However, I want the data to be passed when the Settings View (which contains the UISwitch) is dismissed. Following the third step of this great answer, I'm using UserDefaults to pass the data and trying to use NotificationCenter to update the UserDefaults values when dismissing the Settings View.

To update when user defaults values change, you could have your Settings controller post a Notification when dismissing. Then, other VCs in your app could listen for this notification and update as needed.

I've tried retrieving the notification inside viewDidLoad, but the value doesn't get refreshed because dismissing the Settings View doesn't load the new ViewController everytime.

How can I receive/read a notification every time the Settings View is dismissed? More precisely, where and how would I write the code for reading the notification?


Here's the code for posting the notification:

class SettingsViewController: UIViewController {

@IBAction func doneButton(_ sender: UIButton) {

    self.dismiss(animated: true, completion: nil)
    NotificationCenter.default.post(name: Notification.Name("nSound"), object: nil)

}

Here's the code for retrieving the notification:

    class ViewController: UIViewController {

    @IBOutlet weak var testLabel: UILabel!    
    var savedValue = UserDefaults.standard.bool(forKey: "sound")


    override func viewDidLoad() {
        super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.viewDidLoad), name: Notification.Name("nSound"), object: nil)

//refresh the savedValue variable       
        savedValue = UserDefaults.standard.bool(forKey: "sound")

//test the savedValue variable
        if (savedValue == true) {
            testLabel.text = "yes"
        } else {
            testLabel.text = "no"
        }

    }

2条回答
欢心
2楼-- · 2019-09-06 06:09

The variable savedValue wasn't refreshing itself each time I dismissed the Settings View. This is because the other ViewController wasn't loading itself each time. What I did is I created a new function that runs when the notification is called (which is when Settings View is dismissed). Here is the code:

class ViewController: UIViewController {

@IBOutlet weak var testLabel: UILabel!    
var savedValue = UserDefaults.standard.bool(forKey: "sound")


override func viewDidLoad() {
        super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.retrieveValue), name: Notification.Name("nSound"), object: nil)

//For when the view appears the first time
    savedValue = UserDefaults.standard.bool(forKey: "sound")

    if (savedValue == true) {
        testLabel.text = "yes"
    } else {
        testLabel.text = "no"
    }

}

func retrieveValue() {

//refresh the savedValue variable       
            savedValue = UserDefaults.standard.bool(forKey: "sound")

//test the savedValue variable
            if (savedValue == true) {
                testLabel.text = "yes"
            } else {
                testLabel.text = "no"
            }

    }

Note that addObserver now calls the function retrieveValue().

查看更多
一纸荒年 Trace。
3楼-- · 2019-09-06 06:10

Using notifications won't work very well for this use case, and it's not necessary. I'll refer to the value of the switch as mySetting.

MyViewController (the view controller that will use mySetting)

  • read mySetting from UserDefaults in viewWillAppear(_:) and use it

SettingsViewController (the view controller containing the switch)

  • read mySetting from UserDefaults and assign it to the switch in viewWillAppear(_:)
  • write mySetting to UserDefaults when a valueChanged event is triggered on the switch

Unless you present SettingsViewController in a popover, the viewWillAppear(_:) implementation of MyViewController will be executed when it's newly loaded as well as when you return to it from any other view controller.

查看更多
登录 后发表回答