I have a UITableViewController that has a UITextField in each cell. When the user hits return in a field, it automatically sets the next field to be first responder and scrolls the table to show that field, like this:
- (BOOL) textFieldShouldReturn:(UITextField *)textField
{
UITextField *nextTextField=nil;
NSInteger row;
NSInteger section;
if(textField == self.txtFieldA)
{
nextTextField = self.txtFieldB;
row=1; section=0;
}
else if(textField == self.txtFieldB)
{
nextTextField = self.txtFieldC;
row=2; section=0;
}
else
{
[textField resignFirstResponder];
}
if(nextTextField)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[nextTextField becomeFirstResponder];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
The issue comes when you select a text field (say txtFieldA), scroll the table down so that txtFieldB is not visible, then hit enter. It works as expected on iOS5 (txtFieldB becomes the new first responder). However, on iOS6 it doesn't. It scrolls to the correct spot in the table, but the txtFieldB does not become the first responder (and I'm not sure what is -- when I hit "Back" on my nav controller, the keyboard stays visible).
When I hit "Return", txtFieldB's didBeginEditing isn't fired. If I delay [nextTextField becomeFirstResponder] by a second or so (until the scrolling animation finishes which makes nextTextField visible) it works as expected, but it seems hacky and less smooth to do that so I would rather understand what's going wrong than implement something like that.
In my solution to this problem, I subclassed UITableViewCell to make a text field cell. In that text field cell, I overrode the -setSelected:animated:.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if (selected) {
[self.textField becomeFirstResponder];
}
}
Back in my view controller, when I want to advance to the next field, I just select the row it's in.
- (IBAction)advanceToNextTextField
{
NSIndexPath *indexPath = [self nextIndexPathFromIndexPath:self.indexPathOfActiveField];
[self.tableView selectRowAtIndexPath:indexPath
animated:YES scrollPosition:UITableViewScrollPositionNone];
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionNone animated:YES];
}
This makes handling the the return key easy.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
switch (textField.returnKeyType) {
case UIReturnKeyNext: [self advanceToNextTextField]; break;
case UIReturnKeyDone: [self resignFirstResponder]; break;
default: break;
}
return YES;
}
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With