Search code examples
iosobjective-cuitableviewautolayout

TableView-keyboard animation issue with autolayout


I have a tableView inside a view. Below tableView is a toolbar(with textField in it) and below that is the tabbar. This screen is basically for chatting.

I change view's height when keyboard is displayed (decreasing the height) and also when hidden (increasing the height back to original). It works fine when keyboard is displayed.

Issue is when keyboard is hidden, tableView goes little up with a jerk.

The issue is not with the view's animation because when I put delay in animation, then also tableView goes up with jerk right away (even before view animation has started).

When keyboard is displayed :

enter image description here

While hiding keyboard :

enter image description here

Code to animate decrease in height when keyboard is being displayed (THIS WORKS FINE) :

    // Remove constraint from view
    // Change constraint constant
    // Add constraint to view
    .
    .
    .

    [UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];

    // If at least one chat message
    if ([chatData count] != 0)
    {
        [chatTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([chatData count] - VALUE_ONE) inSection:VALUE_ZERO] atScrollPosition:UITableViewScrollPositionTop animated:NO];
    }

Code to animate increase in height when keyboard is being hidden :

    // Remove constraint from view
    // Change constraint constant
    // Add constraint to view
    .
    .
    .

    [UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];

Solution

  • I see that it was due to change in height of tableView. I was decreasing and increasing it when keyboard is displayed. Also I was scrolling the cells through code using below method, which was changing contentOffset and it was causing jerk.

    [chatTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([chatData count] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    

    The solution is to not to change height of tableView and use below code.

    When keyboard is displayed :

    // Change table contentInset
    UIEdgeInsets contentInset = self.chatTable.contentInset;
    contentInset.bottom = keyboardHeight;
    
    UIEdgeInsets scrollIndicatorInsets = self.chatTable.scrollIndicatorInsets;
    scrollIndicatorInsets.bottom = keyboardHeight;
    
    [UIView animateWithDuration:animationDuration animations:^{
        self.chatTable.contentInset = contentInset;
        self.chatTable.scrollIndicatorInsets = scrollIndicatorInsets;
    }];
    
    // Optional : Display last cell with animation
    if ([chatData count] != 0)
    {
        [chatTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([chatData count] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }
    

    When keyboard is hidden :

    // Reset table contentInset
    UIEdgeInsets contentInset = self.chatTable.contentInset;
    contentInset.bottom = 0.0f;
    
    UIEdgeInsets scrollIndicatorInsets = self.chatTable.scrollIndicatorInsets;
    scrollIndicatorInsets.bottom = 0.0f;
    
    [UIView animateWithDuration:animationDuration animations:^{
        self.chatTable.contentInset = contentInset;
        self.chatTable.scrollIndicatorInsets = scrollIndicatorInsets;
    }];
    
    // Optional : Display last cell with animation
    if ([chatData count] != 0)
    {
        [chatTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([chatData count] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }