15

I am using this other SO answer for adding UITextFields to my UITableViewCells. However, I am now at a loss how I can let the user focus on the next item by using the next button. Any hints?

Community
  • 1
  • 1
Arne
  • 2,494
  • 2
  • 20
  • 43

4 Answers4

13

Try assigning a tag to each UITextField. Once the Next button is pressed, calculate the next tag and use [[UIView viewWithTag:nextTag] becomeFirstResponder] to change the focus to the next text field.

Gabriele Petronella
  • 102,227
  • 20
  • 204
  • 227
Anh
  • 6,474
  • 6
  • 43
  • 57
12

This worked well for me, would have to be tweaked to fit your needs though:

#pragma mark - UITextField Delegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{
    HRCFormCell * currentCell = (HRCFormCell *) textField.superview.superview;
    NSIndexPath * currentIndexPath = [self.tableview indexPathForCell:currentCell];

    if (currentIndexPath.row != [self.questionsArray count] - 1) {

        NSIndexPath * nextIndexPath = [NSIndexPath indexPathForRow:currentIndexPath.row + 1 inSection:0];
        HRCFormCell * nextCell = (HRCFormCell *) [self.tableview cellForRowAtIndexPath:nextIndexPath];

        [self.tableview scrollToRowAtIndexPath:nextIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; 

        [nextCell.textField becomeFirstResponder];
    }

    return YES;
}
Alfie Hanssen
  • 16,366
  • 10
  • 64
  • 71
  • Thanks for the code sample. Provided a good foundation. Although I had to use `UITableViewScrollPositionTop`. – Jason McCreary Jul 02 '12 at 03:54
  • what about going previous?this is not working.But i have modiefied some code like if (isNextClicked==YES) { nextIndexPath = [NSIndexPath indexPathForRow:currentIndexPath.row + 1 inSection:0]; }else{ nextIndexPath = [NSIndexPath indexPathForRow:currentIndexPath.row - 1 inSection:0]; } – karthikeyan Mar 17 '16 at 11:12
  • Its working going previous and last until last row, if i am in last row, its not goes to previous row, its getting crashed – karthikeyan Mar 17 '16 at 11:15
10

In addition to what Anh posted about using the tag value to find the next field and make it firstResponder...

If you are in a UITableView, you also need to keep in mind that the next UITextField might not be on the screen or even in the view because it might be below the bottom of the screen. You might need to scroll that new row into view before making it first responder. What I did in a previous app to handle this was make the tag be a value that I could use to imply the NSIndexPath of the row so I could figure out which row it was in. Then you can scroll that row into view with:

[tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

However, this creates a race condition where the cell isn't visible yet when you call becomeFirstResponder, so I would delay the becomeFirstResponder until it is visible. I would set a value as a property in my class, like the row number, of the field which was supposed to become first responder and then in either cellForRowAtIndexPath or willDisplayCell:forRowAtIndexPath when I'm about to display that cell I would call becomeFirstResponder on the textfield THEN... because then it is guaranteed to exist.

Kenny Wyland
  • 19,242
  • 24
  • 109
  • 205
  • Good point. I will try Anh's answer first, and then implement your extension (right now I have very few cells). – Arne Mar 07 '11 at 18:11
  • 1
    Just use this method to handle the race condition -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{ – MobileMon Dec 17 '12 at 18:52
  • Another note: you can't rely on cellForRowAtIndexPath to retrieve the textfield of the next/previous cell because that cell doesn't exist if it isn't in the view. One solution is to save the index path you want to go to, and then in the didendscrollinganimation method you retrieve the desired textfield there. – shim Jan 18 '13 at 03:29
2

Would do you like ..

NSArray *arrayCells = [self.aTableView visibleCells];

UITableViewCell * currentCell = (UITableViewCell *) textField.superview.superview;
NSIndexPath * currentIndexPath = [self.aTableView indexPathForCell:currentCell];

if ((currentIndexPath.row != [arrayCells count] - 1) && (currentIndexPath.row < [arrayCells count]-1)) {

    NSIndexPath * nextIndexPath = [NSIndexPath indexPathForRow:currentIndexPath.row + 1 inSection:0];
    UITableViewCell * nextCell = (UITableViewCell *) [self.aTableView cellForRowAtIndexPath:nextIndexPath];

    [self.aTableView scrollToRowAtIndexPath:nextIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];

    for (id object in nextCell.contentView.subviews) {
        if ([object isKindOfClass:[UITextField class]]) {
            UITextField *tf = object;
            [tf becomeFirstResponder];
        }
    }
Stephan
  • 37,597
  • 55
  • 216
  • 310
rbbtsn0w
  • 65
  • 10