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

//Somewhere in your UIViewController, like viewDidLoad(){ ... }
self.textField.addTarget(
        self, 
        action: #selector(SearchViewController.textFieldDidChange(_:)),
        forControlEvents: UIControlEvents.EditingChanged
)

参数解释道:

self.textField //-> A UITextField defined somewhere in your UIViewController
self //-> UIViewController
.textFieldDidChange(_:) //-> Can be named anyway you like, as long as it is defined in your UIViewController

然后在你的UIViewController中添加你上面创建的方法:

//Gets called everytime the text changes in the textfield.
func textFieldDidChange(textField: UITextField){

    print("Text changed: " + textField.text!)

}

其他回答

斯威夫特3.1:

选择器:类名。MethodName

  cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged)

  func fieldChanged(textfieldChange: UITextField){

    }

关闭:

   class TextFieldWithClosure: UITextField {
    var targetAction: (() -> Void)? {
        didSet {
            self.addTarget(self, action: #selector(self.targetSelector), for: .editingChanged)
        }
    }

    func targetSelector() {
        self.targetAction?()
    }
    }

和使用

textField.targetAction? = {
 // will fire on text changed
 }

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

迅速:

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

然后,实现回调函数:

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

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