UITextField in UITableView cell becomeFirstResponder programmatically

2.6k Views Asked by At

I have a UITextField with a tag inside a prototype cell. The UITextField is set to become first responder when the UITableView is being built and a UISwitch in the cell above is turned on. This works if the app starts from scratch or if it was closed and restarted. Once it's loaded the [tableView reloadData] doesn't trigger the becomeFirstResponder anymore.

If the UITextField becomes first responder by touching the textfield later on, I can trigger the becomeFirstResponder event with buttons, with pop ups,... But not with my switch any more.

Any pointers as to what I can try?

Currently, I use the didSelectRowAtIndexPath method to trigger a pop up. A nice side effect is, that when I pull up the number keypad, I can provide an ok and cancel button within the pop up instead of having to fiddle with separate buttons on the keypad. But it just seems so obviously to be a workaround.

This is how I call firstresponder when building the UITableView (which works every time the app starts from scratch):

if ([settings doubleForKey:@"limitDouble"]==0 && [settings boolForKey:@"limitBool"]==YES) {
    [dailyLimitEntry becomeFirstResponder];
}

dailyLimitEntry is a UITextField which is strong so it stays around.

Just for fun I added a button and connected it to my code like this:

UITextField *tmp = (UITextField *)[self.view viewWithTag:35];
[tmp becomeFirstResponder];

This works, too. When I use it with the switch, it's only called once the app is freshly loaded in the memory. Otherwise, my UITextField doesn't respond to the switch.

After the first comments, I found a method to check whether or not the UITableView has finished reloading

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if([indexPath row] == ((NSIndexPath*)[[settingsTableView indexPathsForVisibleRows] lastObject]).row){
        //end of loading
        //for example [activityIndicator stopAnimating];
        NSLog(@"finished reload");
        NSLog(@"%@",dailyLimitEntry);
        if ([settings boolForKey:@"limitBool"]==YES) {
            UITextField *tmp = (UITextField *)[self.view viewWithTag:35];
            [tmp becomeFirstResponder];
        }
    }
}

Fun thing though is, become first responder is only triggered the first time the switch is used after the app loaded. Initially, the switch is off. So the cell containing the UITextField is not drawn yet. Once I switch to ON, the UITextField gets drawn in the second cell and becomes first responder. If I switch OFF and ON again, I still get my log "finished reload", but the UITextField doesn't become first responder. It's driving me nuts.... Must be something about the life cycle of the app.

1

There are 1 best solutions below

0
On

Rather than checking the indexPath, check the cell's class.

Here's what I do to bring up the keyboard for a title cell that's blank (when I create a new item):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell isKindOfClass:[FDSSampleTitleCell class]]) {
        FDSSampleTitleCell *titleCell = (FDSSampleTitleCell *)cell;
        if (titleCell.titleField.text.length == 0) {
            [titleCell.titleField becomeFirstResponder];
        }
    }
}