Tuesday, July 6, 2010

UITextField textFieldShouldBeginEditing called twice in iOS4

When you tap UITextField, you get two textFieldShouldBeginEditing calls. This looks like a bug in initial iOS4 release. Workaround is to use a BOOL flag to decide what you should do with that call:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    if (self.allowEdit)
    {
        [self askUser];
        return NO;
    }
    return YES;
}

- (void)askUser
{
    if (self.alertVisible)
        return;    
    self.alertVisible = YES;
    
    UIAlertView *alert =
    [[UIAlertView alloc] initWithTitle:@"Please verify"
                               message:@"Do you want to edit?"
                              delegate:self
                     cancelButtonTitle:@"Cancel"
                     otherButtonTitles:@"Yes",
     nil];
    [alert show];
    [alert release];
}

- (void)alertView:(UIAlertView *)alertView
    clickedButtonAtIndex:(NSInteger)buttonIndex
{
    self.alertVisible = NO;
    if (buttonIndex == 1)
        [self doSomething];
}
The bug will (should) be fixed in some future iOS4 release, so it's more safe to isolate your work-around inside your own routines as much as possible to minimize possible unwanted side-effects.

4 comments:

  1. Thank you! I was struggling with this problem ALL day...didn't realize it could be a bug.

    ReplyDelete
  2. Just make sure you "minimize" the fix, self.alertVisible in my sample code above. One day the bug will be fixed, don't want to debug why something else stopped working at that moment :)

    ReplyDelete
  3. You should check that the UITextField that you are receiving in each call to textFieldShouldBeginEditing is the same object. I ran into a situation myself where I was getting a different object each time for a UITextField delegate call, and it turned out to be an error in setting up my XIB file.

    ReplyDelete
  4. Good tip, have to check my code! Usually I have just one UITextField candidate, handled multiple ones with "activeTextField" pointer.

    ReplyDelete