使用平滑滚动

时间:2018-06-04 09:16:13

标签: ios objective-c uitableview uiscrollview

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

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

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

它们都有相同的滚动问题。我使用scrollToRowAtIndexPath来到UITableView

的底部

我上传了代表模拟相同问题here的演示应用的代码,因此很容易理解。 Here是该问题的视频。任何帮助都非常感谢。

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

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

3 个答案:

答案 0 :(得分:0)

重新加载整个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];

}

希望这会有所帮助:)

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

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