每次要添加或删除行时重新加载表视图会给应用程序的用户带来糟糕的体验。尽管它不是执行此任务的有效方式,但它也有一些负面影响 - 重新加载后选定的行不会保持选中状态,并且更改不会动画。
UITableView
具有为动态更改表视图内容而创建的方法。这些是:
insertRowsAtIndexPaths:withRowAnimation:
moveRowAtIndexPath:toIndexPath:
deleteRowsAtIndexPaths:withRowAnimation:
reloadData
请注意,这些方法允许您指定执行指定操作时将使用的动画类型 - 当您用于修改表格视图的内容时,您无法实现这种行为。
此外,您甚至可以使用表格视图的附加方法组合多个表格视图操作(这不是必需的):
开始更新结束更新
只需将您想要执行的操作包装到调用beginUpdates
和endUpdates
方法中,表格视图将为在调用之间请求的所有操作创建一个beginUpdates
动画,endUpdates
以便整个过渡看起来比由几个单独的动画创建的效果更好。
[self.tableView beginUpdates]
//calls to insert/move and delete methods
[self.tableView endUpdates]
保持数据源状态与UITableView
. 出于这个原因,您必须确保当表视图开始执行请求的操作时,其数据源将返回正确的值。
[self.tableView beginUpdates]
//calls to insert/move and delete methods
//operations on our data source so that its
//state is consistent with state of the table view
[self.tableView endUpdates]
表视图何时开始执行操作?这取决于操作是否在beginUpdates
和endUpdates
方法定义的动画块中。endUpdates
如果是,则表视图在方法调用后开始执行操作。否则,表视图在调用插入/移动或删除方法后立即执行操作。
当您使用beginUpdates
和endUpdates
方法在表视图上执行操作时,您必须知道在这种情况下,表视图“批处理”请求的操作并以特定顺序执行它们,这与您在表视图上进行的调用顺序不必相同对象(Apple 关于此主题的文档)。
要记住的最重要的事情是删除所有操作总是在所有插入操作之前执行。此外,当插入操作按升序执行(索引 1、2、3 的操作)时,删除操作似乎按降序执行(索引 3、2、1 的操作)。请记住,这对于保持数据源状态与表视图保持一致至关重要。
花一些时间分析对数据源和表视图的操作顺序,如下面的示例所示。
最后一个例子:
//initial state of the data source
self.numbers = [@[@(0), @(1), @(2), @(3), @(4), @(5), @(6)] mutableCopy];
//
//...
//
NSArray indexPathsToRemove = @[[NSIndexPath indexPathForRow:3 section:0].
[NSIndexPath indexPathForRow:0 section:0];
NSArray indexPathsToAdd = @[[NSIndexPath indexPathForRow:6 section:0],
[NSIndexPath indexPathForRow:5 section:0]];
[self.tableView beginUpdates];
[self.numbers removeObjectAtIndex:3];
[self.numbers removeObjectAtIndex:0];
[self.numbers insertObject:@(10) atIndex:4];
[self.numbers insertObject:@(11) atIndex:5];
[self.tableView insertRowsAtIndexPaths:indexPathsToAdd withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
//final state of the data source ('numbers') - 1, 2, 4, 5, 6, 10, 11