自动布局的UITableView键盘动画问题

时间:2014-03-03 08:07:55

标签: ios objective-c uitableview autolayout

我在视图中有一个tableView。 tableView下面是一个工具栏(里面有textField),下面是tabbar。这个屏幕基本上是为了聊天。

我在显示键盘时(降低高度)以及隐藏时(将高度增加回原始高度)更改视图的高度。显示键盘时它可以正常工作。

问题是当键盘被隐藏时,tableView几乎没有一个混蛋。

问题不在于视图的动画,因为当我将延迟放在动画中时,tableView也会立即出现混蛋(甚至在视图动画开始之前)。

显示键盘时

enter image description here

隐藏键盘:

enter image description here

显示键盘时动画降低的动画代码(此工作精细):

    // 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];
    }

隐藏键盘时动画高度增加的代码:

    // 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];

3 个答案:

答案 0 :(得分:6)

我看到它是由于tableView的高度发生变化。当键盘显示时,我正在减少并增加它。此外,我使用下面的方法滚动单元格代码,这正在改变contentOffset并导致混蛋。

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

解决方案是不要改变tableView的高度并使用下面的代码。

显示键盘时

// 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];
}

隐藏键盘时

// 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];
}

答案 1 :(得分:1)

而不是更改框架动画,你应该在显示键盘时调整tableView的contentInset / contentOffset

tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, heightOfYourKeyboardAndStuff, 0.0);
[tableView setContentOffset: CGPointMake(0.0, -heightOfYourKeyboardAndStuff) animated: YES];

,反之亦然,隐藏键盘

[tableView setContentOffset: CGPointMake(0.0, preferedValue) animated: YES];
tableView.contentInset = UIEdgeInsetsZero;

在我的经验中,这非常顺利!使用自定义算术计算heightOfYourKeyboardAndStuff和preferedValue以满足您的需求。

ps:您可能需要在显示/隐藏键盘之前存储/恢复当前的contentOffset。

答案 2 :(得分:0)

在为ListView添加固定高度时在Xamarin中遇到此问题通过添加自定义渲染器来解决它然后

 UIKit.UIKeyboard.Notifications.ObserveWillShow((sender, args) =>
            {
                //to extend the space between your content and the edges
                Control.ContentInset = new UIEdgeInsets(0,0,0,0);
            });
            UIKit.UIKeyboard.Notifications.ObserveWillHide((sender, args) =>
            {
                Control.ContentInset = new UIEdgeInsets(0,0,0,0);
            });