我如何检测文本字段中的任何文本变化?委托方法shouldChangeCharactersInRange适用于某些东西,但它并没有完全满足我的需求。因为在它返回YES之前,textField文本对其他观察器方法是不可用的。

例如,在我的代码calculateAndUpdateTextFields没有得到更新的文本,用户已经键入。

是他们的任何方式得到类似textChanged Java事件处理程序。

- (BOOL)textField:(UITextField *)textField 
            shouldChangeCharactersInRange:(NSRange)range 
            replacementString:(NSString *)string 
{
    if (textField.tag == kTextFieldTagSubtotal 
        || textField.tag == kTextFieldTagSubtotalDecimal
        || textField.tag == kTextFieldTagShipping
        || textField.tag == kTextFieldTagShippingDecimal) 
    {
        [self calculateAndUpdateTextFields];

    }

    return YES;
}

当前回答

Swift 4版本

使用键值观察 通知对象对其他对象属性的更改。

var textFieldObserver: NSKeyValueObservation?

textFieldObserver = yourTextField.observe(\.text, options: [.new, .old]) { [weak self] (object, changeValue) in
  guard let strongSelf = self else { return }
  print(changeValue)
}

其他回答

这里是相同的swift版本。

textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)

func textFieldDidChange(textField: UITextField) {

}

谢谢

我解决了改变shouldChangeChractersInRange行为的问题。如果你返回NO,这些更改不会被iOS内部应用,相反,你有机会手动更改它,并在更改后执行任何操作。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //Replace the string manually in the textbox
    textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
    //perform any logic here now that you are sure the textbox text has changed
    [self didChangeTextInTextField:textField];
    return NO; //this make iOS not to perform any action
}

迅速:

yourTextfield.addTarget(self, action: #selector(yourHandler(textField:)), for: .editingChanged)

然后,实现回调函数:

@objc final private func yourHandler(textField: UITextField) {
    print("Text changed")
}

从iOS 14开始,不需要创建选择器,你可以通过一个闭包来传递一个UIAction:

let editingChanged = UIAction { _ in
    // Do something when text changes...
}
myTextField.addAction(editingChanged, for: .editingChanged)

KVO解决方案不起作用

KVO不工作在iOS控件:http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html

在观察课上,你要这样做:

假设你知道你想要观看的文本视图:

var watchedTextView: UITextView!

这样做:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(changed),
    name: UITextView.textDidChangeNotification,
    object: watchedTextView)

但是,要注意:

很可能你只想调用它一次,所以不要在layoutSubviews中调用它 在抚养孩子的过程中,很难知道什么时候最好。这取决于你的情况。不幸的是,没有标准的、固定的解决方案 例如,你通常肯定不能在初始化时调用它,因为当然watchedTextView可能还不存在

.

下一个问题是……

当以编程方式更改文本时,不会调用任何通知。

这是iOS工程中一个巨大的、古老的、愚蠢的麻烦。

当.text属性以编程方式更改时,控件根本不会调用通知。

这是非常烦人的,因为每个应用程序都以编程方式设置文本,比如在用户发布后清除字段,等等。

你必须像这样子类化文本视图(或类似的控件):

class NonIdioticTextView: UIITextView {

    override var text: String! {
        // boilerplate code needed to make watchers work properly:
        get {
            return super.text
        }
        set {
            super.text = newValue
            NotificationCenter.default.post(
                name: UITextView.textDidChangeNotification,
                object: self)
        }

    }

}

(提示-不要忘记超级电话必须在之前到来!邮政电话。)

没有可用的解决方案,除非您通过上面所示的子类化来修复控件。这是唯一的解决方案。

注意,通知

UITextView.textDidChangeNotification

结果

func textViewDidChangeSelection(_ textView: UITextView) 

被称为。

(不是textViewDidChange。)