As you know, 動(dòng)態(tài)刪除TableView cell的方法為:
[weakSelf.dataSource removeObjectAtIndex:indexPath.row]; [tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
即先刪數(shù)據(jù)源再在Updates
內(nèi)部刪除row
以上代碼在方法
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
是沒有問題的举农。
有問題的是需要點(diǎn)擊cell
內(nèi)部按鈕序仙,在cell方法中使用刪除方法時(shí)谬返,比如使用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]);
}];
...
}
假設(shè)當(dāng)前數(shù)據(jù)源中有兩條記錄,倒敘刪除cell(先刪第二條光涂,再刪第一條)庞萍,以上的log打印為:
刪除1:1
刪除2:1
剩余:1
刪除2:0
剩余:0
并沒有問題,但如果正序刪除忘闻,log打印為:
刪除1:1
刪除2:1
剩余:1
刪除2:1
crash于[weakSelf.dataSource removeObjectAtIndex:indexPath.row];
很簡(jiǎn)單钝计,因?yàn)閐ataSource中的[1]已經(jīng)刪除,只有1條數(shù)據(jù)了齐佳。
同時(shí)私恬,在方法:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"section:%ld row:%ld", indexPath.section, indexPath.row);
打印當(dāng)前僅存的cell信息,顯示:
section:2 row:0
row
已經(jīng)為0炼吴。
問題:
刪除一個(gè)cell后本鸣,numberOfRowsInSection
、didSelectRowAtIndexPath
方法中row
已經(jīng)變?yōu)?code>0硅蹦,而cellForRowAtIndexPath
方法依然為1
荣德。因此在繼續(xù)使用index.row
去刪除數(shù)據(jù)源中的元素時(shí),引起crash
解決方法:
- 通過所點(diǎn)擊的button獲取正常的IndexPath
UITableViewCell *cell = (UITableViewCell *)[[btn superview] superview];
NSIndexPath *indexPath = [weakSelf.customTableView indexPathForCell:cell];
- 刪除cell后童芹,刷新section
[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
這種方法簡(jiǎn)單直接涮瞻。但是如果當(dāng)前只有一個(gè)section,這種方法與[tableView reloadData]
,沒有區(qū)別假褪,使用動(dòng)態(tài)刪除也就沒有意義署咽。