我有以下代码示例:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[namesArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
和
if ([nameSection count] == 0)
{
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView beginUpdates];
[indexKeys removeObjectAtIndex:section];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
注意顺序....在第一个例子中我首先从数组中删除对象,然后从tableview中删除该行。
在第二个例子中,我将从tableview中删除该行,然后从我的数组中删除该部分,然后从tableview中删除该部分。
这是正确的做事顺序吗?或者我应该首先从UI中删除它,然后是数组?
我问的原因是因为我收到一些报告这些崩溃的用户,我似乎无法重复:
NSInternalInconsistencyException - 无效更新:第1部分中的行数无效 更新(0)后必须包含在现有部分中的行 等于
之前该部分中包含的行数
使用此堆栈跟踪:
1: libobjc.A.dylib objc_exception_throw 32
2: CoreFoundation [NSException raise:format:] 0
3: Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 90
4: UIKit -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] 6042
5: UIKit -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] 254
6: UIKit -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] 26
7: Movies _mh_execute_header 253319
8: UIKit -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] 84
9: CoreFoundation -[NSObject performSelector:withObject:withObject:] 52
10: UIKit -[UIApplication sendAction:to:from:forEvent:] 62
答案 0 :(得分:3)
您应该首先更新数据模型 ,否则表格视图会对正确的行数和部分数量感到困惑。
答案 1 :(得分:3)
表处于编辑模式后,表视图将询问数据源是否 每行都应该是可编辑的。如果tableView:canEditRowAtIndexPath:方法是 实现后,依次调用每一行。
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return NO;
}
return YES;
}
确定是否可以编辑行后,表视图会询问代理 每行应使用哪种编辑样式:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
当点击删除按钮时,tableView将tableView:commitEditingStyle:forRowAtIndexPath:消息发送到数据源。它需要三个参数:
1)对tableView本身的引用(如果数据源需要区分多个tableViews)。
2)刚刚被点击的控件的UITableViewCellEditingStyle - 在这种情况下,UITableViewCellEditingStyleDelete
3)定位相关行的indexPath对象。
当数据源收到commitEditingStyle:forRowAtIndexPath:消息时,它需要做两件事:
1)通过删除表中行所代表的对象来更新tableView的模型。请记住,表本身只是一个视图,除非我们实际从模型中删除对象,否则下次重新加载表时它将重新出现在表中。
2)将tableView:deleteRowsAtIndexPath:withRowAnimation:message发送到tableView,以便更新表格显示。在这种情况下,因为我们正在处理删除,它会将删除的单元格向左滑动,然后将其下方的单元格向上移动以缩小间隙。
-(void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableData removeObjectAtIndex:indexPath.row];
NSArray *indexPathArray = [NSArray arrayWithObject:indexPath];
[tableView deleteRowsAtIndexPaths:indexPathArray
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
有一系列表格单元格插入和删除动画可供选择:
关于如何使用表格的好书是here。