在canEditRowAtIndexPath方法,UITableView reloadData不能正常工作?

在我的应用程序,我重新加载我的TableView [tablView reloadData];从TableView删除行后,然后canEditRowAtIndexPath方法canEditRowAtIndexPath呼吁(前)总行数。

例如:

如果我有我的TableView 5行,然后我从tableView删除1行。 删除后,我重新加载我的TableView [tablView reloadData] ),canEditRowAtIndexPath方法调用5次而不是4次

所以我总是得到以下错误:

由于未捕获exception'NSRangeException', 原因: ' * ** – [__ NSArrayM objectAtIndex:]:index 5 beyond bounds [0..4]'

我也尝试了一些延迟(使用NSTimer )后重新加载表,但它也没有为我工作。

我在这里放一些代码:

我应用canEditRowAtIndexPath在特定的行上,这个@"status" isEqualToString:@"directory"

 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"%d", self.listOfSounds.count); // Return NO if you do not want the specified item to be editable. if([[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"status"] isEqualToString:@"directory"]) return YES; else return NO; } 

删除行的代码:

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array [self updateListofSoundsFile]; /// Custom method } } - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath { return NO; // i also tried to return YES; } 

这里updateListofSoundsFile是我自定义的方法代码是:

 -(void)updateListofSoundsFile { if(self.listOfSounds.count > 0) [self.listOfSounds removeAllObjects]; self.listOfSounds = [self.sql_ getAllDataFromAudioTable]; // get all record from DB NSLog(@"%d",self.listOfSounds.count); [self.tblView reloadData]; } 

请给出任何build议,我该如何解决这个问题?
谢谢 :)

你需要从tableview删除原始也befor从数组中删除项目,并重新加载数据使用这一行becouse从数组中删除项目,但不是tableview。

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array [self updateListofSoundsFile]; /// Custom method } } 

我遇到了同样的问题。 问题是我删除了单元格的对象,但是当我使用tableViewreloadData方法时,我的canEditRowAtIndexPath方法没有被调用,导致能够编辑我不想编辑的单元格。 真正的修复不是调用deleteRowsAtIndexPaths方法,而是[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 方法。

基本上这是发生了什么事情:

当我调用reloadData :Nitin说,原始数据没有从tableView中移除。 所以这不是解决办法。

当我调用deleteRowsAtIndexPaths :iOS检测到底层数据和单元格数量之间的差异(因为我已经删除了底层对象)。 结果是一个崩溃,这也不是解决scheme(显然)。

现在修复!

当我调用reloadRowsAtIndexPaths :这导致tableView简单地重新加载单个单元格,并摆脱了原始数据。 这是解决scheme。

而不是删除dataSource对象,然后尝试删除在这一点上基本上什么都不支持的单元格(这会导致崩溃),只需删除dataSource对象,然后重新加载tableView indexPath

以下是该方法的一般格式:

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [myDataSourceArray removeObjectAtIndex:indexPath.row]; [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } } 

这是我第一次碰到这个问题,剩下的原始数据并没有通过简单的调用reloadData方法来解决。 这当然是迄今为止我见过的最优雅的解决scheme。

快乐编码! 我希望这有帮助。

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array [self updateListofSoundsFile]; /// Custom method } [self.tblView reloadData]; } 

谈到我,我分析如下:

正如rmaddyNitin Gohel's回答中所评论的rmaddy

  1. 更新表之前,应始终从数据源中删除数据。

    我觉得这是理想的方式。

  2. 如果你要调用reloadData ,没有理由首先调用deleteRowsAtIndexPath

    这看起来也是正确的。

我分析歧义,如果我写reloadData其崩溃,但一旦我写deleteRowsAtIndexPath它运作良好。

希望有人会为此而强调这个问题。

'removeObjectAtIndex:indexPath'需要一些时间,我怀疑你的[self.tblView reloadData]被提前调用。 我试过一个示例代码,发现成功与[UiTableView beginUpdates][UiTableView endUpdates]你也可以避免崩溃,如果你在重新加载或删除行之前没有尝试过

 [tableTable beginUpdates]; [tableArray removeObjectAtIndex:indexPath.row]; [tableTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableTable endUpdates];