Swift 3
Note: this answer is for Swift 3. My other answer takes advantage of the much nicer API in Swift 4.
I would use Key Value Observation for this purpose. It has the nice property of using using standardized #keyPath
Strings to identify changes, rather than Notifications' arbitrary Strings.
The [.initial, .new]
options make it so that observeValue(forKeyPath:of:change:context:)
is called for you right away (to set the initial value), and after every change (to be notified of new values).
public final class AppConfig: NSObject {
static let shared = AppConfig()
override private init() {}
@objc dynamic var fadedTextColor: UIColor = .red
@objc dynamic var textHeaderColor: UIColor = .blue
// ... add other global config state properties here
// any pro properties you wish to observe must be `@objc` and ` dynamic`
}
class PopupButton: UIButton {
override func awakeFromNib() {
let appconfig = AppConfig.shared
self.layer.borderWidth = 1.3
appconfig.addObserver(self,
forKeyPath: #keyPath(AppConfig.fadedTextColor),
options: [.initial, .new], context: nil)
self.layer.cornerRadius = 10
self.layer.backgroundColor = UIColor.white.cgColor
appconfig.addObserver(self,
forKeyPath: #keyPath(AppConfig.textHeaderColor),
options: [.initial, .new], context: nil)
}
override func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard let keyPath = keyPath, let newValue = change?[.newKey] else { return }
if object as? AppConfig == AppConfig.shared {
switch (keyPath, newValue) {
case (#keyPath(AppConfig.fadedTextColor), let fadedTextColor as UIColor):
self.layer.borderColor = fadedTextColor.cgColor
case (#keyPath(AppConfig.textHeaderColor), let textHeaderColor as UIColor):
self.setTitleColor(textHeaderColor, for: .normal)
// Handle other changes here
default: break
}
}
}
}