问题
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"
}
}
回答1:
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.
回答2:
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().
来源:https://stackoverflow.com/questions/42494633/receiving-a-notification-without-loading-the-view