我如何检测文本字段中的任何文本变化?委托方法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)
}

其他回答

XenElement的答案是正确的。

以上也可以在接口构建器中通过右键单击UITextField并将“Editing Changed”发送事件拖放到你的子类单元中来完成。

Swift 3版本:

class SomeClass: UIViewController, UITextFieldDelegate { 

   @IBOutlet weak var aTextField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

        aTextField.delegate = self
        aTextField.addTarget(self, action: #selector(SignUpVC.textFieldDidChange), for: UIControlEvents.editingChanged)        
    }

   func textFieldDidChange(_ textField: UITextField) {

       //TEXT FIELD CHANGED..SECRET STUFF

   }

}

不要忘记设置委托。

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

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

迅捷用户界面

如果你正在使用原生的SwiftUI TextField或只是使用UIKit UITextField(这里是如何),你可以观察文本的变化,如:

SwiftUI 2.0

从iOS 14, macOS 11,或任何其他包含SwiftUI 2.0的操作系统中,有一个名为.onChange的新修饰符,用于检测给定状态的任何变化:

struct ContentView: View {
    @State var text: String = ""

    var body: some View {
        TextField("Enter text here", text: $text)
            .onChange(of: text) {
                print($0) // You can do anything due to the change here.
                // self.autocomplete($0) // like this
            }
    }
}

SwiftUI 1.0

对于旧的iOS和其他SwiftUI 1.0平台,你可以在combine框架的帮助下使用onReceive:

import Combine
.onReceive(Just(text)) { 
    print($0)
}

注意,您可以使用文本。publisher而不是Just(text),但它返回的是更改的值而不是整个值。

我解决了改变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
}