通过按钮修改UITextField.text时如何监听值变化?
原因说明
UIKit原生设计下,只有用户通过键盘交互修改UITextField内容时,才会触发editingChanged事件和对应的代理回调,编程式直接修改text属性不会主动触发这些回调。
可行方案
以下三种方案可根据场景选择:
方案1:手动触发事件(改动最小,适合单一场景)
在编程修改text属性后,手动调用sendActions触发editingChanged事件,原有监听逻辑无需改动:
@IBAction func change_minutes(_ sender: Any) { txtMinute.text = "123" // 手动触发编辑变更事件 txtMinute.sendActions(for: .editingChanged) }
方案2:KVO监听text属性(无需手动触发,适合多位置修改text的场景)
使用KVO监听text属性,只要属性值被赋值就会收到回调,无需每次修改时手动加触发代码:
// 类内声明观察者属性 private var textObserver: NSKeyValueObservation? override func viewDidLoad() { super.viewDidLoad() // 绑定KVO监听 textObserver = txtMinute.observe(\.text, options: [.new]) { [weak self] _, change in guard let self = self, let newText = change.newValue as? String else { return } print(newText) self.enableEditButton() } }
注意:页面销毁时无需手动移除观察者,基于block的KVO会在观察者对象释放时自动解除绑定。
方案3:自定义UITextField子类(适合全局复用该逻辑的场景)
重写text属性的didSet方法,统一处理值变更回调,适合多处需要监听编程修改text的项目:
// 自定义TextField类 class CustomTextField: UITextField { // 对外暴露值变更回调 var textDidUpdate: ((String?) -> Void)? override var text: String? { didSet { textDidUpdate?(text) // 也可以在这里全局触发editingChanged事件,兼容原有监听逻辑 sendActions(for: .editingChanged) } } }
使用时将txtMinute的类设置为CustomTextField,再绑定回调即可:
txtMinute.textDidUpdate = { [weak self] newText in print(newText ?? "") self?.enableEditButton() }
内容的提问来源于stack exchange,提问作者Qazi Ammar
相关产品推荐
相关产品推荐

