在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 } }
我遇到了同样的问题。 问题是我删除了单元格的对象,但是当我使用tableView
的reloadData
方法时,我的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]; }
谈到我,我分析如下:
正如rmaddy
在Nitin Gohel's
回答中所评论的rmaddy
:
-
更新表之前,应始终从数据源中删除数据。
我觉得这是理想的方式。
-
如果你要调用
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];