Reputation: 3961
I have subclassed a UIButton to use throughout my project. These UIButton subclasses will have a border color that changes based on what the user selects in the settings. The setting is saved with UserDefaults.
Problem: When I load up the App for the first time, the button border is the correct color - however, when I change settings (to ultimately change the button border) - nothing happens. The buttons only change color once I close out of the App and re-open.
My code
class CustomSeasonButton: UIButton {
var seasonCold = Bool()
let nsDefaults = UserDefaults.standard
var notification = Notification(name: Notification.Name(rawValue: "themeChanged"))
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// ...
self.seasonCold = nsDefaults.bool(forKey: "savedSeasonDefault")
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshButtonBorder), name: notification.name, object: nil)
refreshButtonBorder()
}
func refreshButtonBorder() {
print("Notification Received")
if seasonCold {
seasonCold = false
self.layer.borderColor = UIColor.blue
}
else {
seasonCold = true
self.layer.borderColor = UIColor.red
}
}
}
Settings
class SettingsVC: UITableViewController {
//...
var notification = Notification(name: Notification.Name(rawValue: "themeChanged"))
//...
}
And then in the IBAction of the season select - I have the following:
NotificationCenter.default.post(notification)
So as you may see from my code above, the button border color should be switching between Blue and Red, depending on what's selected with the UserDefaults.
The only way I can get the border color to change is if I close the App and reopen it.
Question: How can I make sure the UIButton subclasses get a border color change every time the settings (UserDefaults) is updated? Thanks!
Upvotes: 0
Views: 84
Reputation: 427
seasonCold = false {
didSet {
refreshButtonBorder()
}
}
func refreshButtonBorder() {
if seasonCold {
self.layer.borderColor = UIColor.blue
}
else {
self.layer.borderColor = UIColor.red
}
}
and set seasonCold whenever you change userdefaults "savedSeasonDefault"
for one to many calls use NotificationCenter, every instance of the subclassed button should have a NotificationObserver, and post the notification whenever UserDefaults changes
var notification = Notification(name: Notification.Name(rawValue: "seasonChanged"))
in awake from nib or your init function
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshButtonBorder), name: notification.name, object: nil)
whenever season cold changes sprinkle notification dust
NotificationCenter.default.post(notification)
Upvotes: 2
Reputation: 23701
For your buttons to change on-the fly, they would have to know that the settings have changed. They would have to listen to a broadcast message of some sort and take some action when the settings are modified. One way to do that might be through the NSNotificationCenter -- all your buttons when they are created could listen on the default notification center for a message, then when you note that the settings have changed you could broadcast a message.
As for your code above, note that you are setting the border color in the init
method. That method is called exactly once, when the button is created. That explains why your button's border colors don't change... their color is established when they are created.
Finally, it may be of interest to you (if you don't know about it) to learn more about [UIAppearance][1]
and the way it allows you to affect the colors and styles of entire groups of controls at once.
Upvotes: 1