3
votes

I have problem with a long form in iOS. The form itself is done with a static table view. For the form I needed a toolbar with prev/next and done. In this project I added BSKeyboardControls, and I've allready done it myself in another project.

The toolbar works fine except when the next or previous textField/textView is out of sight. Then the focus on the former textField won't change and I'm still typing in this text field. When I now scroll manually and the targeted next textfield appears it magically becomes the first responder. This is of course not the expected behabier.

So I figured out I would have to scroll the table view to the respective fields before trying to set them as first responder. But I connot get this done.

I've tried to this with indexPathes

NSIndexPath *path = [self.tableView indexPathForCell:(UITableViewCell *)textField.superview.superview];
[self.tableView scrollToRowAtIndexPat:path atScrollPosition:UITableViewScrollPositionTop animated:YES];

Although the super-superview is a valid (and the right) table cell, the path returned is nil. I also tried some variations

CGPoint point = [self.tableView convertPoint:textField.frame.origin toView:self.tableView];
NSIndexPath *path = [self.tableView indexPathForRowAtPoint:point];

and other variations with rects and indexPathsForRowsInRect.

The only way is to manually keep track of the textFields cell indexPaths, but that is no suitable solution in this case.

Anybody has an idea of how to achieve scrolling to an out of sight textField in a tableView?

Edit:

As Justin Paulson requested the code of keyboardControlsPreviousNextPressed:

- (void)keyboardControlsPreviousNextPressed:(BSKeyboardControls *)controls withDirection:(KeyboardControlsDirection)direction andActiveTextField:(id)textField
{
    NSIndexPath *path = [self.tableView indexPathForCell:(UITableViewCell *)((UIView *)textField).superview.superview];
    NSLog(@"path %@ for cell %@", path, ((UIView *)textField).superview.superview);
    [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
    [textField becomeFirstResponder];
}

As I said according to the output of the log the path is nil, whereas the super-superview is the rught table view cell

1
Do you use UIViewController or UITableViewController as the base of your VC class? One of the advantages of using UITableViewController is that when you assign a UITextField for example to become the first responder, the UITableViewController will automatically scroll so that the field is visible (thus not below the keyboard for example)Ladislav
What does your code look like for this delegate function : keyboardControlsPreviousNextPressed:withDirection:andActiveTextField:?Justin Paulson
thanks for the fast responses. @Ladislav Im using UITableViewController but it does not automatically scroll.patman
@Justin Paulson I'll edit the question and paste the code.patman
Why not just have all the UITextFields saved in an NSArray, so that when Next is clicked you just find the appropriate UITextField and let him become first responder...Ladislav

1 Answers

3
votes

Thanks for trying to help me, i've a solution myself. In my keyboardControlsPreviousNextPressed i have now

[self.tableView scrollRectToVisible:((UIView *)textField).superview.superview.frame animated:YES];
[textField becomeFirstResponder];

This solution seems to work quite well. The only problem i've encountered is that sometimes the newly focused textField is hidden by the keyboard, so the tableViewController doesn't adjusts itself automatically. You could additionally scroll the row to the top to circumvent this in most cases.

NSIndexPath *path = [self.tableView indexPathForCell:(UITableViewCell *)textField.superview.superview];
[self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];