0

I have a UITableView, which I am controlling from a custom UIViewController. When the user clicks the 'add' button, I add a row to the UITableView with a text field in it, and make it the first responder. The problem is, when the bottom of the table is out of view (or hidden by the keyboard), the UITableView doesn't scroll to bring the text field into view.

UITableViewController does this automatically, but my View Controller can't be a subclass of UITableViewController.

nornagon
  • 15,393
  • 18
  • 71
  • 85
  • possible duplicate of [Scroll UITextField above Keyboard in a UITableViewCell on a regular UIViewController](http://stackoverflow.com/questions/15036519/scroll-uitextfield-above-keyboard-in-a-uitableviewcell-on-a-regular-uiviewcontro) – Salman Hasrat Khan Aug 07 '15 at 05:23

4 Answers4

9

I fixed this by twiddling contentInset on the UITableView when the keyboard appears or disappears.

- (void)registerForKeyboardNotifications {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasHidden:)
                                                 name:UIKeyboardDidHideNotification object:nil];
}

- (void)keyboardWasShown:(NSNotification *)aNotification {
    CGRect keyboardBounds;
    [[aNotification.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
    keyboardHeight = keyboardBounds.size.height;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0);
    [UIView commitAnimations];
    [tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[items count] inSection:0]
                     atScrollPosition:UITableViewScrollPositionMiddle
                             animated:YES];
}

- (void)keyboardWasHidden:(NSNotification *)aNotification {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    tableView.contentInset = UIEdgeInsetsZero;
    [UIView commitAnimations];
}

call registerForKeyboardNotifications when you load the UITableView, and everything else should Just Work.

nornagon
  • 15,393
  • 18
  • 71
  • 85
  • [tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[items count] inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; What do "items" mean here? – iOSDev Oct 27 '10 at 06:51
  • In case anyone's interested in how UIKit handles the animations in this case (I had the same problem), read here: http://www.cocoabuilder.com/archive/cocoa/316466-resizing-uitableview-will-keeping-content-scrolled-to-bottom.html – Kasper Munck Aug 08 '12 at 15:55
0

work for ios5

UITextField *activeField;

// Called when the UIKeyboardDidShowNotification is sent.

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
   activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
   activeField = nil;
}

// Called when the UIKeyboardWillHideNotification is sent

- (void)keyboardWasShown:(NSNotification *)aNotification {


   id view = [activeField superview];
   while (view && ![view isKindOfClass:[UITableViewCell class]]) 
   {
      view = [view superview];
   }
   UITableViewCell *cell = view;
   NSIndexPath *indexPath = [tableview indexPathForCell:cell];
   CGRect keyboardBounds;
   [[aNotification.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
   [UIView beginAnimations:nil context:nil];
   [UIView setAnimationBeginsFromCurrentState:YES];
   tableview.contentInset = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0);
   [UIView commitAnimations];
   [tableview scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

}

- (void)keyboardWasHidden:(NSNotification *)aNotification {
   [UIView beginAnimations:nil context:nil];
   [UIView setAnimationBeginsFromCurrentState:YES];
    tableview.contentInset = UIEdgeInsetsZero;
   [UIView commitAnimations];
}
hans
  • 117
  • 1
  • 6
0

I found -scrollToRowAtIndexPath:atScrollPosition:animated: and guess this would do what you want.

Thomas Müller
  • 15,565
  • 6
  • 41
  • 47
  • It doesn't, because the `UITableView` is still the height of the whole screen (and covered by the keyboard). – nornagon Jun 08 '10 at 08:35