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

   }

}

不要忘记设置委托。

其他回答

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。)

设置事件监听器。

[self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

真正倾听:

- (void)textFieldDidChange:(UITextField *)textField {
    NSLog(@"text changed: %@", textField.text);
}
[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(didChangeTextViewText:) 
name:UITextFieldTextDidChangeNotification object:nil];



- (void) didChangeTextViewText {
 //do something
}

一个是你可能有多个uitextfield。所以,给他们一个标签,然后你可以打开标签。下面是如何在任何类中设置一个观察者。

private func setupTextFieldNotification() {
    NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: nil, queue: OperationQueue.main) { (notification) in
        if let textField = notification.object as? UITextField, textField.tag == 100, let text = textField.text {
            print(#line, text)
        }
    }
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

我们可以很容易地从Storyboard中配置,按CTRL拖动@IBAction并更改事件,如下所示: