注:原文是苹果官方文档中的《Batch Insertion, Deletion, and Reloading of Rows and Sections》
UITableView可以同一时间进行批量插入、删除和重载,这些动作可以指定动画。下面是八个相关的操作方法:
- (void)beginUpdates;
- (void)endUpdates;
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
注意:reloadSections:withRowAnimation:和reloadRowsAtIndexPaths:withRowAnimation:是iOS3.0以后才有的,这个可以让你的tableView进行部分刷新,进而避免使用reloadData方法。
在调用批量插入、删除和重载方法时,应该在beginupdates和endupdates定义动画块中调用。否则可能无效.beginupdates和endupdates可以嵌套调用。
endupdates执行完之后,tableView要调用相应的数据源和代理方法,所以,在调用这些插入删除方法之前应该先把数据源准备好(删除插入响应的数据源)。
批量删除和插入的例程
要在tableView中插入和删除,首先要准备好数据源的数组。在删除和插入动作执行后,将会调用相应的(插入的)数据源和代理。
其次,调用beginUpdates方法,准备开始,然后调用insertRowsAtIndexPaths:withRowAnimation:,deleteRowsAtIndexPaths:withRowAnimation:, insertSections:withRowAnimation:或 deleteSections:withRowAnimation:。
最后,调用 endUpdates方法。
- (IBAction)insertAndDeleteRows:(id)sender {
// original rows: Arizona, California, Delaware, New Jersey, Washington
[states removeObjectAtIndex:4]; // Washington
[states removeObjectAtIndex:2]; // Delaware
[states insertObject:@"Alaska" atIndex:0];
[states insertObject:@"Georgia" atIndex:3];
[states insertObject:@"Virginia" atIndex:5];
NSArray *deleteIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:2 inSection:0],
[NSIndexPath indexPathForRow:4 inSection:0],
nil];
NSArray *insertIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:0 inSection:0],
[NSIndexPath indexPathForRow:3 inSection:0],
[NSIndexPath indexPathForRow:5 inSection:0],
nil];
UITableView *tv = (UITableView *)self.view;
[tv beginUpdates];
[tv insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
[tv deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[tv endUpdates];
// ending rows: Alaska, Arizona, California, Georgia, New Jersey, Virginia
}
例子中,删除了两个item,插入了三个item。
操作的执行顺序
在上面的例子中,你肯注意到 deleteRowsAtIndexPaths:withRowAnimation:方法写在 insertRowsAtIndexPaths:withRowAnimation:之后。然而,这并不是tableView真正的操作顺序。实际上,所有的插入和重载都会在删除动作完成之后才执行
下面是一个删除和插入效果示意:
1.Begin updates.
2.Delete row at index 1 of section at index 0.
3.Delete section at index 1.
4.Insert row at index 1 of section at index 1.
5.End updates.
写在最后
tableView的删除和插入,使用的时候还是要非常细心的,它和reloadData不一样,一不小心就会crash。要说的就是,在执行删除和插入之前,一定要把数据源准备妥妥的。如果增加了三条数据源,那么就得插入三条cell,少插入一条cell都不行,都一条那就更不行了。总之,插入或删除的cell是和数据源一一对应的。