0

I have an embedded tableview within a view. The top rows of this embedded table view are always visible, even with the keyboard. If you enter something into the lower cells I want them to scroll up (as usual) in order to see what you're entering into the textfields. However this doesn't happen and they remain hidden behind the keyboard. How can I change this?

Thx Michael

MichiZH
  • 5,587
  • 12
  • 41
  • 81

3 Answers3

0

You don't get that behavior for free, you need to scroll the content up/down yourself. A UITableView inherits from a UIScrollView, so scrolling is not the actual problem. To scroll, you can set its contentSize and contentOffset (even animated if you like).

The first thing is, you want to listen to these notifications:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

These will tell you whether the keyboard will show or hide. In each of these methods, change the contentOffset and contentSize of your UITableView accordingly:

- (void)keyboardWillShow:(NSNotification *)notification
{
    // keyboard info
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationOptions animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    NSTimeInterval animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    // offsets
    UIView *cell = myTextField.superView; // assuming your text field is a direct child of the UITableViewCell
    CGFloat textFieldBottomY = self.view.frame.origin.y + myTableView.frame.origin.y - myTableView.contentOffset.y + cell.frame.origin.y + myTextField.origin.y + myTextField.frame.size.height;
    CGFloat keyboardTopY = keyboardRect.origin.y;

    // new content size: add size to be able to scroll
    originalContentOffset = myTableView.contentOffset; // store the original content offset to set back when keyboard hides
    originalContentSize = myTableView.contentSize; // store the original content size to set back when keyboard hides
    CGSize newContentSize = myTableView.contentSize;
    newContentSize.height += keyboardRect.size.height;
    myTableView.contentSize = newContentSize;

    // scroll to just beneath your text field
    [UIView animateWithDuration:animationDuration delay:0 options:animationCurve animations:^{
        myTableView.contentOffset = CGPointMake(0, textFieldBottomY - keyboardTopY);
    } completion:NULL];
}

To reset everything:

- (void)keyboardWillHide:(NSNotification *)notification
{
    // keyboard info
    NSDictionary *userInfo = [notification userInfo];
    UIViewAnimationOptions animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    NSTimeInterval animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    // move content
    [UIView animateWithDuration:animationDuration delay:0 options:animationCurve animations:^{
        myTableView.contentOffset = originalContentOffset;
    } completion:^(BOOL finished) {
        if (finished) {
            // reset content size
            myTableView.contentSize = originalContentSize;
        }
    }];
}

To detect which text field is selected/active:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    myTextField = textField;
}

I didn't test out the code on a UITableView, but I used it very recently on a UIScrollView. Again - since a UITableView inherits from a UIScrollVIew, this should not be a problem. If the table view does not scroll correctly to just beneath the text field, the value of textFieldBottomY is incorrect.

Eugene Dudnyk
  • 5,553
  • 1
  • 23
  • 48
mmvie
  • 2,571
  • 7
  • 24
  • 39
0

Here is a link with a detailed explanation to achieve this. It explains the method on UIScrollView, which will also work on UITableView.

If you had used a UITableViewController instead of manually adding UITableView on a view, you would had got the behavior automatically.

Adithya
  • 4,545
  • 3
  • 25
  • 28
0

You have to scroll to the position between the TextField and Tableview, check this answer.

Community
  • 1
  • 1
fpauer
  • 356
  • 3
  • 9