【问题标题】:Insert last row in UITableView with smooth scrolling在 UITableView 中插入最后一行并平滑滚动
【发布时间】: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)。

标签: ios objective-c uitableview uiscrollview


【解决方案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模拟器中测试这个
  • 是的,这个问题在模拟器上不会出现,请在设备上试试。
  • 模拟器也出现这个问题,让我看看设备
  • 您没有在视频中遇到问题?
猜你喜欢
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多