ios UITextField 文本更改事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7010547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:02:08  来源:igfitidea点击:

UITextField text change event

iosobjective-cswiftevent-handlinguitextfielddelegate

提问by karim

How can I detect any text changes in a textField? The delegate method shouldChangeCharactersInRangeworks for something, but it did not fulfill my need exactly. Since until it returns YES, the textField texts are not available to other observer methods.

如何检测 textField 中的任何文本更改?委托方法shouldChangeCharactersInRange适用于某些事情,但它并不能完全满足我的需要。因为在它返回 YES 之前,textField 文本对其他观察者方法不可用。

e.g. in my code calculateAndUpdateTextFieldsdid not get the updated text, the user has typed.

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

Is their any way to get something like textChangedJava event handler.

他们有什么办法可以得到类似textChangedJava 事件处理程序的东西。

- (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;
}

回答by Daniel G. Wilson

From proper way to do uitextfield text change call back:

正确的方式来做 uitextfield 文本更改回调

I catch the characters sent to a UITextField control something like this:

我捕获发送到 UITextField 控件的字符,如下所示:

// Add a "textFieldDidChange" notification method to the text field control.

In Objective-C:

在 Objective-C 中:

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

In Swift:

在斯威夫特:

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

Then in the textFieldDidChangemethod you can examine the contents of the textField, and reload your table view as needed.

然后在该textFieldDidChange方法中,您可以检查 textField 的内容,并根据需要重新加载您的表格视图。

You could use that and put calculateAndUpdateTextFieldsas your selector.

您可以使用它并将calculateAndUpdateTextFields作为您的selector.

回答by William T.

XenElement's answer is spot on.

XenElement 的回答很到位。

The above can be done in interface builder too by right-clicking on the UITextField and dragging the "Editing Changed" send event to your subclass unit.

通过右键单击 UITextField 并将“Editing Changed”发送事件拖到您的子类单元,也可以在界面构建器中完成上述操作。

UITextField Change Event

UITextField 更改事件

回答by asdf

to set the event listener:

设置事件监听器:

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

to actually listen:

实际聆听:

- (void)textFieldDidChange:(UITextField *)textField {
    NSLog(@"text changed: %@", textField.text);
}

回答by Juan Boero

Swift:

迅速:

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

Then, implement the callback function:

然后,实现回调函数:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}

回答by ercolemtar

As stated here: UITextField text change event, it seems that as of iOS 6(iOS 6.0 and 6.1 checked) it is not possible to fully detect changes in UITextFieldobjects just by observing the UITextFieldTextDidChangeNotification.

如此处所述:UITextField 文本更改事件,似乎从 iOS 6(已检查 iOS 6.0 和 6.1)开始,UITextField仅通过观察UITextFieldTextDidChangeNotification.

It seems that only those changes made directly by the built-in iOS keyboard are tracked now. This means that if you change your UITextFieldobject just by invoking something like this: myUITextField.text = @"any_text", you won't be notified about any changes at all.

现在似乎只跟踪由内置 iOS 键盘直接进行的那些更改。这意味着,如果您UITextField只是通过调用这样的东西来更改您的对象:myUITextField.text = @"any_text",您根本不会收到任何更改通知。

I don't know if this is a bug or it is intended. Seems like a bug since I haven't found any reasonable explanation in documentation. This is also stated here: UITextField text change event.

我不知道这是一个错误还是有意为之。似乎是一个错误,因为我在文档中没有找到任何合理的解释。这也在此处说明:UITextField text change event

My "solution" to this is to actually post a notification by myself for every change I make to my UITextField(if that change is done without using the built-in iOS keyboard). Something like this:

我对此的“解决方案”实际上是我自己为我所做的每项更改发布通知UITextField(如果该更改是在不使用内置 iOS 键盘的情况下完成的)。像这样的东西:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

NSNotification *myTextFieldUpdateNotification  = 
  [NSNotification notificationWithName:UITextFieldTextDidChangeNotification
                  object:myUITextField];

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

This way you are 100% confident that you'll receive the same notification when you change the .textproperty of your UITextFieldobject, either when you update it "manually" in your code or through the built-in iOS keyboard.

通过这种方式,您可以 100% 地确信在更改对象的.text属性时会收到相同的通知UITextField,无论是在代码中“手动”更新它还是通过内置的 iOS 键盘。

It is important to consider that, since this is not a documented behavior, this approach may lead to 2 notifications received for the same change in your UITextFieldobject. Depending on your needs (what you actually do when your UITextField.textchanges) this could be an inconvenience for you.

考虑到这一点很重要,因为这不是记录在案的行为,因此这种方法可能会导致收到 2 个针对UITextField对象中相同更改的通知。根据您的需求(您在UITextField.text更改时实际执行的操作),这可能会给您带来不便。

A slightly different approach would be to post a custom notification (this is, with a custom name other than UITextFieldTextDidChangeNotification) if you actually need to know whether the notification was yours or "iOS-made".

UITextFieldTextDidChangeNotification如果您确实需要知道该通知是您的还是“iOS 制造的”,则一种稍微不同的方法是发布自定义通知(即,使用除 之外的自定义名称)。

EDIT:

编辑:

I've just found a different approach which I think could be better:

我刚刚找到了一种我认为可能更好的不同方法:

This involves the Key-Value Observing (KVO)feature of Objective-C (http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA).

这包括键-值观察(志愿)(Objective-C的特征http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid /10000177-BCICJDHA)。

Basically, you register yourself as an observer of a property and if this property changes you get notified about it. The "principle" is quite similar to how NSNotificationCenterworks, being the main advantage that this approach works automatically also as of iOS 6 (without any special tweak like having to manually post notifications).

基本上,您将自己注册为属性的观察者,如果该属性发生变化,您会收到有关它的通知。“原理”与NSNotificationCenter工作原理非常相似,这是该方法从 iOS 6 开始自动工作的主要优点(无需任何特殊调整,例如必须手动发布通知)。

For our UITextField-scenario this works just fine if you add this code to, for example, your UIViewControllerthat contains the text field:

对于我们的UITextField-scenario,如果您将此代码添加到例如UIViewController包含文本字段的内容中,则效果很好:

static void *myContext = &myContext;

- (void)viewDidLoad {
  [super viewDidLoad];

  //Observing changes to myUITextField.text:
  [myUITextField addObserver:self forKeyPath:@"text"
    options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld 
    context:myContext];

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context {

  if(context == myContext) {
    //Here you get notified every time myUITextField's "text" property is updated
    NSLog(@"New value: %@ - Old value: %@",
      [change objectForKey:NSKeyValueChangeNewKey],
      [change objectForKey:NSKeyValueChangeOldKey]);
  }
  else 
    [super observeValueForKeyPath:keyPath ofObject:object 
      change:change context:context];

}

Credit to this answer regarding "context" management: https://stackoverflow.com/a/12097161/2078512

归功于这个关于“上下文”管理的答案:https: //stackoverflow.com/a/12097161/2078512

Note: Seems like while you are in the process ofediting a UITextFieldwith the built-in iOS keyboard, the "text" property of the text field is not updated with every new letter typed/removed. Instead, the text field object gets updated "as a whole" after you resign the first responder status of the text field.

注意:似乎在您使用内置 iOS 键盘编辑 a的过程中UITextField,文本字段的“文本”属性不会随着输入/删除的每个新字母而更新。相反,在您退出文本字段的第一响应者状态后,文本字段对象会“作为一个整体”更新。

回答by bikram sapkota

We can easily configure that from Storyboard, CTRL drag the @IBActionand change event as following:

我们可以很容易地从Storyboard、CTRL 拖动@IBAction和更改事件进行配置,如下所示:

enter image description here

在此处输入图片说明

回答by Hindu

Here in swift version for same.

这里有相同的 swift 版本。

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

func textFieldDidChange(textField: UITextField) {

}

Thanks

谢谢

回答by Pauls

I resolved the issue changing the behavior of shouldChangeChractersInRange. If you return NO the changes won't be applied by iOS internally, instead you have the opportunity to change it manually and perform any actions after the changes.

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

回答by kemicofa ghost

Swift Version tested:

Swift 版本测试:

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

Parameters explained:

参数说明:

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

Then add the method you created above in your UIViewController:

然后将您在上面创建的方法添加到您的UIViewController

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

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

}

回答by acidgate

Swift 4

斯威夫特 4

func addNotificationObservers() {

    NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidChangeAction(_:)), name: .UITextFieldTextDidChange, object: nil)

}

@objc func textFieldDidChangeAction(_ notification: NSNotification) {

    let textField = notification.object as! UITextField
    print(textField.text!)

}