detecting the change of content of UITextField when the change is not made by the keyboard

11,314

Solution 1

Maybe simple key-value observing will work?

[textField addObserver:self forKeyPath:@"text" options:0 context:nil];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"text"] && object == textField) {
        // text has changed
    }
}

Edit: I just checked it, and it works for me.

Solution 2

You can add the UITextFieldTextDidChangeNotification:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(textFieldChanged:)
                                             name:UITextFieldTextDidChangeNotification
                                           object:textField];

textField (param object) is your UITextField. selector is your method that will be called when this notification was fired.

Solution 3

You can handle text change within UIControlEventEditingChanged event. So when you change text programmaticaly just send this event:

textField.text = @"This is a test string";
[textField sendActionsForControlEvents:UIControlEventEditingChanged];

Solution 4

The delegate method may actually work for you. You get the text field, the range that will change, and the new string. You can put these together to determine the proposed string.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range        replacementString:(NSString *)string
{
    NSMutableString *proposed = [NSMutableString stringWithString:textField.text];
    [proposed replaceCharactersInRange:range withString:string];
    NSLog(@"%@", proposed);
    // Do stuff.
    return YES; // Or NO. Whatever. It's your function.
}

Solution 5

This is a pretty robust solution, but it should work. In your function that is called when you press the button...

NSString *string = [NSString stringWithFormat:@"This is a test string"];
if(string == textfield.text){
...
}

Or, you can us a self scheduler to check if it has changed repeatedly.

Share:
11,314
JAHelia
Author by

JAHelia

Updated on June 29, 2022

Comments

  • JAHelia
    JAHelia almost 2 years

    I have a UIButton and a UITextField,when the button is pressed the textfield's content string will be equal to: This is a test string, how can I detect that this text field has changed its contents in this case?

    p.s. UITextField's delegate methods do not work in such case

    UPDATE: I want this behavior to be on iOS 6+ devices.

  • JAHelia
    JAHelia over 11 years
    it sounds there is a bug in iOS 6, because it doesn't work on iOS6 and works on iOS 5, I will update the question.
  • Sebastian
    Sebastian over 11 years
    I think Apple changed this behaviour. In this question (stackoverflow.com/questions/12754948/…) it's the same problem. I didn't test it under iOS 6.
  • JAHelia
    JAHelia over 11 years
    this is a manual triggering of the event, in a large project this is impractical to send the event with every text change.
  • Alexey Kozhevnikov
    Alexey Kozhevnikov over 11 years
    Should not test NSString or any NSObject equality using ==
  • Alexey Kozhevnikov
    Alexey Kozhevnikov about 11 years
    The problem with it is that UIKit is not KVO-compliant
  • idStar
    idStar over 10 years
    This worked for me, while the UITextFieldDelegate method 'textField:shouldChangeCharactersInRange:replacementString:' would always fire one character short of the current contents, and the 'addTarget:action:forControlEvents:' approach, whether in code or in IB (Storyboard) would have the action never fire! I would imagine this is a bug (I'm on iOS7.0.2). Thankfully, the notification approach described in @Sebastian's answer, worked perfectly.
  • Martin Berger
    Martin Berger over 6 years
    This is one character late.Use notification stackoverflow.com/a/13952247/233333