UITextField text change event

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

How can I detect any text changes in a textField? The delegate method shouldChangeCharactersInRange works 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.

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

Is their any way to get something like textChanged Java event handler.

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

回答1:

From proper way to do uitextfield text change call back:

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

// Add a "textFieldDidChange" notification method to the text field control. [textField addTarget:self                action:@selector(textFieldDidChange:)      forControlEvents:UIControlEventEditingChanged];

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

You could use that and put calculateAndUpdateTextFields as your selector.



回答2:

XenElement's answer is spot on.

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.



回答3:

to set the event listener:

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

to actually listen:

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


回答4:

Swift:

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

Then, implement the callback function:

@objc func textFieldDidChange(textField: UITextField){  print("Text changed")  }


回答5:

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 UITextField objects just by observing the 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 UITextField object just by invoking something like this: myUITextField.text = @"any_text", you won't be notified about any changes at all.

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.

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:

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 .text property of your UITextField object, either when you update it "manually" in your code or through the built-in iOS keyboard.

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 UITextField object. Depending on your needs (what you actually do when your UITextField.text changes) this could be an inconvenience for you.

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".

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

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 NSNotificationCenter works, being the main advantage that this approach works automatically also as of iOS 6 (without any special tweak like having to manually post notifications).

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

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" pro  
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!