【问题标题】:Swift UITextField subclass handle text change programmaticallySwift UITextField 子类以编程方式处理文本更改
【发布时间】:2016-01-29 21:53:27
【问题描述】:

我有一个UITextField 的子类,专门用于处理日期文本。我有一个使用此文本字段的tableviewcell

let dateInput: DateTextField

现在控制器需要在显示之前初始化dateInput的文本如下:

cell.dateInput.text = "01/29/2016"

现在,我希望能够检测到文本从子类更改,以便我可以更新内部日期变量,使其与文本同步。

我实现了文本字段委托方法,但这只是捕捉用户所做的更改,而不是通过编程方式。

【问题讨论】:

  • 也许只有我一个人,但我不明白你要做什么......你能详细说明一下或者说清楚一点吗?
  • 我有一个 UItextField 的子类,它只显示日期字符串。控制器正在以编程方式设置文本 (dateTextField.text="01/12/2015")。所以我想弄清楚如何捕捉到文本已经改变,以便我可以更新 DateTextField 类中的一些后端变量。这样解释更好吗?
  • 既然我们在这里讨论字符串,为什么不直接做 if condition where (dateInput.text == "01/29/2016")...?这可以在 viewWillAppear 等初始方法中完成,并基于该方法对后端进行异步调用

标签: ios swift nsdate


【解决方案1】:

您可以覆盖属性并在您的自定义类中添加didSet 观察者:

class DateTextField: UITextField {

    override var text: String? {
        didSet {
           // Do your stuff here    
        }
    }   
}

【讨论】:

  • 这正是我想要的。谢谢!
  • 内部 iOS 例程不使用“text”或“attributedText”属性,它们仅供外部使用。例如,当用户在您的文本字段上键入时,内部事件是获取 textField 值的唯一方法,因为 UIKit 仅更改内部变量,而不是“text”或“attributedText”属性。
  • 如果您将文本设置在某处 (textField.text = "some text") 并且您希望 UITextField 子类在此之后做出响应,则此方法非常有效。
【解决方案2】:

对此我的解决方案是让子类的每个实例都维护自己的UITextFieldDidChange 通知,并使用自定义协议将该信息传递给侦听器。

protocol MutableTextFieldDelegate {
    func textChanged(_ sender:MutableTextField)
}

class MutableTextField : UITextField {

    var textChangedDelegate : MutableTextFieldDelegate?

    var previousValue : String?

    override func awakeFromNib() {
        super.awakeFromNib()
        NotificationCenter.default.addObserver(forName: .UITextFieldTextDidChange, object: self, queue: nil) { [weak self] notification in
            guard let strongSelf = self else { return }
            guard let object = notification.object as? MutableTextField, object == strongSelf else { return }

            if strongSelf.previousValue != strongSelf.text {
                strongSelf.textChangedDelegate?.textChanged(strongSelf)
            }
            strongSelf.previousValue = strongSelf.text
        }
    }
}

swift5:NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification ...

【讨论】:

  • 这里不要忘记删除deinit()上的观察者,否则这些观察者会永远逗留
  • 这不再是真的。 “从 iOS 9(和 OS X 10.11)开始,如果你不使用基于块的观察者,你不需要自己删除观察者。系统会为你做这件事,因为它对观察者使用归零弱引用,在哪里可以。” stackoverflow.com/a/40339926/916299
  • 感谢提醒!我注意到了,因为他们实际上在这里使用了一个闭包
  • 上面的例子使用了基于块的观察者,所以后面需要去掉。
【解决方案3】:

检查 UIControlEventEditingChanged 事件...在其中,您可以设置以下逻辑。

来自this 帖子的示例:

// Add a "textFieldDidChange" notification method to the text field control.
[textField addTarget:self 
              action:@selector(textFieldDidChange:) 
    forControlEvents:UIControlEventEditingChanged];

【讨论】:

  • 感谢更新,但在 iOS9 中设置文本时未调用 textFieldDidChange (dateTextField.text = "12/01/2015")。
猜你喜欢
  • 2011-11-11
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2013-01-16
  • 2012-05-16
相关资源
最近更新 更多