在 UITableView 中插入最后一行并平滑滚动

Posted

技术标签:

【中文标题】在 UITableView 中插入最后一行并平滑滚动【英文标题】:Insert last row in UITableView with smooth scrolling 【发布时间】:2018-06-04 09:16:13 【问题描述】:

我正在尝试创建一个类似聊天机器人的应用程序,我使用了带有自定义单元格的 UITableView 来满足我的需求。每当添加新消息时,我都会创建并插入一个新行,然后滚动到UITableView 的底部。一切正常,直到某一点,但是当单元格的高度发生变化时(我有两种不同类型的单元格),动画很混乱,它不能平滑滚动到最后并且整个UITableView 闪烁,这是不是很好的用户体验。我尝试了几种方法:

1 - 将数据添加到数据源数组并重新加载UITableView,然后滚动到底部。

2 - 使用 insertRowsAtIndexPaths 然后滚动到底部。

他们都有滚动的相同问题。我已经使用scrollToRowAtIndexPath 到达了UITableView 的底部

我已经上传了一个演示应用程序的代码,它代表模拟相同的问题here,所以它很容易理解。 Here 是该问题的视频。非常感谢任何帮助。

此问题可能不会出现在模拟器上,请在设备上运行演示项目。

在阅读了所有的 cmets 并在聊天中进行讨论后,我注意到 iPhone 5C (10.3.3) 上发生了这种情况。我在 iPhone 5S (11.3) 上运行了演示,没有出现问题。不确定这是否与操作系统有关。

【问题讨论】:

第一种方法行不通,但第二种方法肯定行得通。我检查了您共享的代码,第二种方法运行良好。 不,它没有。如果您使用模拟器,我建议您在设备上运行它。该问题不会出现在模拟器上。 我在 iPhone X 上检查过。让我在其他设备上试试。您使用的是哪种设备? iPhone SE,让我也看看 iPhone 6S。 试着找出你的代码大部分时间都花在了哪里。然后你可以努力提高速度。您可以为此使用 Instruments(Xcode 中的 Command-I)。 【参考方案1】:

重新加载整个 tableview 会导致滚动混乱,而不是在最后一个位置插入行。

在您的操作方法中进行以下更改

- (IBAction)btnLargeCellClicked:(id)sender     // To add large green colored row.

    /************ This is the FIRST approach. ***********/
    [arrHeight addObject:@"100"];
    [arrData addObject:@"1"];
    NSIndexPath* ip = [NSIndexPath indexPathForRow:[_myTable numberOfRowsInSection:0] inSection:0];
    [_myTable insertRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade];
    [self scrollTableviewToLastRow];


    /************ This is the SECOND approach. ***********/
//    [arrHeight addObject:@"100"];
//    [_myTable beginUpdates];
//    NSIndexPath *row1 = [NSIndexPath indexPathForRow:arrData.count inSection:0];
//    [arrData insertObject:@"1" atIndex:arrData.count];
//    [_myTable insertRowsAtIndexPaths:[NSArray arrayWithObjects:row1, nil] withRowAnimation:UITableViewRowAnimationFade];
//    [_myTable endUpdates];
//    [self scrollTableviewToLastRow];

还有

- (IBAction)btnClicked:(id)sender      // To add small red colored row.
    /************ This is the FIRST approach. ***********/
    [arrHeight addObject:@"50"];
    [arrData addObject:@"1"];
    NSIndexPath* ip = [NSIndexPath indexPathForRow:[_myTable numberOfRowsInSection:0] inSection:0];
    [_myTable insertRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade];
    [self scrollTableviewToLastRow];


    /************ This is the SECOND approach. ***********/
//    [arrHeight addObject:@"50"];
//    [_myTable beginUpdates];
//    NSIndexPath *row1 = [NSIndexPath indexPathForRow:arrData.count inSection:0];
//    [arrData insertObject:@"1" atIndex:arrData.count];
//    [_myTable insertRowsAtIndexPaths:[NSArray arrayWithObjects:row1, nil] withRowAnimation:UITableViewRowAnimationFade];
//    [_myTable endUpdates];
//    [self scrollTableviewToLastRow];


希望这会有所帮助:)

【讨论】:

对不起,这和我注释掉的第二种方法不一样吗? 是的,与注释代码相同 :) 您在使用该注释代码时遇到什么问题? 随机添加两个单元格时(在两种方法中),滚动到表格底部并不顺畅。请查看视频,OP中的链接。 您发布的视频是没有注释的代码输出,被注释的不会产生可怕的滚动...此外,您可以通过添加UIView animateWithDuration:方法获得更流畅的动画 是的,确实如此,如果你随机添加几个单元格,在某个点之后滚动是可怕的。我什至玩过animateWithDuration,没有运气。【参考方案2】:

看到你的源之后,可以说 tableView reloadData 每次都重新加载单元格,这使得动画每增加一个单元格就更加忙碌。 为了您的目标,您应该使用另一个系统:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates]; 

而且,也许你最后也需要 scrollToRowAtIndexPath

【讨论】:

第二种方法也不好用,我也不明白需要重新加载插入的行吗?! 那是戏剧性的解释,reloadData 做到了。您应该使用不同类型的 tableView 更新,例如按钮点击上的“reloadRowsAtIndexPaths”【参考方案3】:

你需要这个,改变下面的第二种方法

[arrHeight addObject:@"50"];
//    [_myTable beginUpdates];
    NSIndexPath *row1 = [NSIndexPath indexPathForRow:arrData.count inSection:0];
    [arrData insertObject:@"1" atIndex:arrData.count];
    [_myTable insertRowsAtIndexPaths:[NSArray arrayWithObjects:row1, nil] withRowAnimation:UITableViewRowAnimationNone];
    [_myTable reloadRowsAtIndexPaths:@[row1] withRowAnimation:UITableViewRowAnimationNone];

//    [_myTable endUpdates];
    [self scrollTableviewToLastRow];

【讨论】:

不起作用,我也不明白需要重新加载正在插入的行。 这里不闪,我在iphonex模拟器中测试这个 是的,这个问题在模拟器上不会出现,请在设备上试试。 模拟器也出现这个问题,让我看看设备 您没有在视频中遇到问题?

以上是关于在 UITableView 中插入最后一行并平滑滚动的主要内容,如果未能解决你的问题,请参考以下文章

uitableview 的最后一行中的值发生变化

UITableView 在插入更多行时滚动到顶部

UITableView帧高度动画故障

在 UITableView 中使用插入行

在我的 UiTableView 中看不到最后一行

如何在iOS中的UITableView的最后一行添加一行字符串?