As you know, 动态删除TableView cell的方法为:
[weakSelf.dataSource removeObjectAtIndex:indexPath.row]; [tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
即先删数据源再在Updates
内部删除row
以上代码在方法
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
是没有问题的。
有问题的是需要点击cell
内部按钮,在cell方法中使用删除方法时,比如使用cell赋block的方式
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...
__weak typeof(self) weakSelf = self;
NSLog(@"删除1:%ld",(long)indexPath.row);
[cell setTapDeleteBlock:^(UIButton *btn) {
NSLog(@"删除2:%ld",(long)indexPath.row);
[weakSelf.dataSource removeObjectAtIndex:indexPath.row];
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
NSLog(@"剩余:%ld",[tableView numberOfRowsInSection:2]);
}];
...
}
假设当前数据源中有两条记录,倒叙删除cell(先删第二条,再删第一条),以上的log打印为:
删除1:1
删除2:1
剩余:1
删除2:0
剩余:0
并没有问题,但如果正序删除,log打印为:
删除1:1
删除2:1
剩余:1
删除2:1
crash于[weakSelf.dataSource removeObjectAtIndex:indexPath.row];
很简单,因为dataSource中的[1]已经删除,只有1条数据了。
同时,在方法:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"section:%ld row:%ld", indexPath.section, indexPath.row);
打印当前仅存的cell信息,显示:
section:2 row:0
row
已经为0。
问题:
删除一个cell后,numberOfRowsInSection
、didSelectRowAtIndexPath
方法中row
已经变为0
,而cellForRowAtIndexPath
方法依然为1
。因此在继续使用index.row
去删除数据源中的元素时,引起crash
解决方法:
- 通过所点击的button获取正常的IndexPath
UITableViewCell *cell = (UITableViewCell *)[[btn superview] superview];
NSIndexPath *indexPath = [weakSelf.customTableView indexPathForCell:cell];
- 删除cell后,刷新section
[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
这种方法简单直接。但是如果当前只有一个section,这种方法与[tableView reloadData]
,没有区别,使用动态删除也就没有意义。
网友评论