我有标签,按钮,视图等的自定义类。
示例类:
class PopupButton: UIButton {
override func awakeFromNib() {
self.layer.borderWidth = 1.3
self.layer.borderColor = fadedTextColor.cgColor
self.layer.cornerRadius = 10
self.layer.backgroundColor = whiteColor.cgColor
self.setTitleColor(textHeaderColor, for: .normal)
}
}
当我更改颜色即:fadedTextColor
时,我希望此PopupButton
类能够立即反映该更改。
我怎样才能做到这一点?
感谢您的时间。
答案 0 :(得分:1)
首先,您创建一个单例类来保存所有“全局”变量。然后将didSet添加到fadedTextColor属性以在其值更改时发布通知。接下来在自定义类中添加一个观察者和一个选择器,使用单例类中的颜色更改按钮边框颜色:
colfunc <- colorRampPalette(c("red", "blue"))
colfunc(10)
class Shared {
private init() {}
static let instance = Shared()
var fadedTextColor: UIColor = .red {
didSet {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "fadedTextColorChanged"), object: nil)
}
}
var textHeaderColor: UIColor = .blue
}
答案 1 :(得分:0)
注意:这个答案适用于Swift 3. My other answer利用Swift 4中多更好的API。
我会为此目的使用键值观察。它具有使用标准化#keyPath
字符串来识别更改而不是通知的任意字符串的良好属性。
[.initial, .new]
选项使得observeValue(forKeyPath:of:change:context:)
立即为您调用(设置初始值),并在每次更改后(通知新值)。
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
}
}
}
}
答案 2 :(得分:0)
我们在Swift 4中有一个非常好但文档很差的API,它使用KeyPath
来实现简洁,类型安全的键值观察。需要处理所有回调的大量observeValue(forKeyPath:of:change:context:)
已经不复存在了。相反,每个观察都采用一个闭包,只有在与它有关的事件发生时才会调用。这很好地打破了你的observeValue(forKeyPath:of:change:context:)
方法。
有关详细信息,请参阅2017年WWDC的What's New in Foundation视频,从19:30开始。
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`
}
import UIKit
class PopupButton: UIButton {
var observers = [NSKeyValueObservation]()
override func awakeFromNib() {
let appconfig = AppConfig.shared
self.layer.borderWidth = 1.3
observers.append(appconfig.observe(\.fadedTextColor, options: [.initial, .new]) { object, change in
self.layer.borderColor = object.fadedTextColor.cgColor
})
self.layer.cornerRadius = 10
self.layer.backgroundColor = UIColor.white.cgColor
observers.append(appconfig.observe(\.textHeaderColor, options: [.initial, .new]) { object, change in
self.setTitleColor(object.textHeaderColor, for: .normal)
})
}
}