xcode 尝试删除单元格和部分时 UITableView 崩溃
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10269714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UITableView crashes when trying to delete a cell and section
提问by insanj
I've been working on creating a UITableView that has its content loaded from a NSUserDefaults object. Whenever I attempt to delete a cell/section, however, the program crashes and spits out the following:
我一直致力于创建一个 UITableView,它的内容是从 NSUserDefaults 对象加载的。但是,每当我尝试删除单元格/部分时,程序都会崩溃并输出以下内容:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1030
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (2) must be equal to the number of sections contained in the table view before the update (3), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).
No matter how much I read up on this error and try to fix it, I've been stuck here for the past few hours. Here is my method that is called when the user taps the "delete" button:
无论我读了多少关于这个错误并尝试修复它,过去几个小时我都被困在这里。这是我在用户点击“删除”按钮时调用的方法:
(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//[[[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"] removeObjectAtIndex:indexPath.row];
//[[[NSUserDefaults standardUserDefaults] objectForKey:@"rawDates"] removeObjectAtIndex:indexPath.row];
NSMutableArray *rawArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"];
NSMutableArray *rawDates = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawDates"];
[rawArray removeObjectAtIndex:indexPath.row];
[rawDates removeObjectAtIndex:indexPath.row];
[[NSUserDefaults standardUserDefaults] setObject:rawArray forKey:@"rawArray"];
[[NSUserDefaults standardUserDefaults] setObject:rawDates forKey:@"rawDates"];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];
}
}
and here are the methods used to determine number of rows and cells:
以下是用于确定行数和单元格数的方法:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawDates"] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawDates"] objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
The last method in there returns a one because, as of right now, I plan on only have one cell per each section. Thank you for taking the time to look over here, and I really hope you can help me out! :/
那里的最后一个方法返回一个,因为截至目前,我计划每个部分只有一个单元格。感谢您抽出时间来看这里,我真的希望您能帮助我!:/
回答by Paul.s
Check out the Batch Insertion, Deletion, and Reloading of Rows and Sections
Basically you need to put any calls of these method
基本上你需要把这些方法的任何调用
- (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;
between
之间
- (void)beginUpdates;
- (void)endUpdates;
e.g.
例如
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];
[tableView endUpdates];
Your dataSource also needs to reflect the changes by the time endUpdates is called
您的数据源还需要在调用 endUpdates 时反映更改
Personally I like to make a category to give a block based wrapper around this to
就我个人而言,我喜欢创建一个类别来为此提供一个基于块的包装器
- stop me forgetting to call
endUpdates
- it allows indentation to look right / be automatic
- 别让我忘记打电话
endUpdates
- 它允许缩进看起来正确/是自动的
Category on UITableView
分类在 UITableView
@interface UITableView (PSAdditions)
- (void)ps_updates:(void (^)(void))updateBlock;
@end
@implementation UITableView (PSAdditions)
- (void)ps_updates:(void (^)(void))updateBlock;
{
[self beginUpdates];
if (updateBlock) { updateBlock(); }
[self endUpdates];
}
Which would look like this
看起来像这样
[tableView ps_updates:^{
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];
}];