3

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.

rog
  • 5,351
  • 5
  • 33
  • 40
Mike73
  • 51
  • 1
  • 6
  • please show the code where you call `becomeFirstResponder` – KDaker Oct 18 '12 at 23:03
  • Do you have a method that is called when you toggle your switch? If yes, post that code. If not, then you need to set that up so that you call becomeFirstResponder when the switch is turned on. – lnafziger Oct 19 '12 at 03:06
  • I have used the same code as in the button example with a switchvalue changed event. – Mike73 Oct 19 '12 at 16:35
  • With the button working, I think it's a matter of timing. Is there some call where I can check whether or not the tableview has reloaded the data? I think it comes from the switch being operated, which calls for the tabledata to reload and once that's done, I can set focus on the textfield. – Mike73 Oct 19 '12 at 20:34
  • my guess is that willDisplayCell and becomeFirstResponder are two methods that'll try to run on the main thread, and the tableView method gets higher priority while the becomeFirstResponder message gets discarded. Try delaying the call to [tmp becomeFirstResponder]; by using performSelector: afterDelay: – Nitin Alabur May 19 '13 at 23:46

1 Answers1

2

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];
        }
    }
}
stevex
  • 5,589
  • 37
  • 52