在我的应用程序中,我从TableView中删除行后重新加载我的TableView ([tablView reloadData];
),然后canEditRowAtIndexPath
方法总是要求(pervious)总行数。
例如:
如果我的TableView上有 5 行,那么我会从tableView中删除 1 行。删除后,我重新加载我的TableView ([tablView reloadData]
)但canEditRowAtIndexPath
方法调用 5次而不是 4次 ??
所以我总是得到以下错误:
由于未捕获的异常'NSRangeException'终止应用,原因:' * ** - [__ NSArrayM objectAtIndex:]:索引5超出边界[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];
}
请提出任何建议,我该如何解决这个问题? 谢谢:))
答案 0 :(得分:5)
你需要从tableview中删除raw也可以从数组中删除项目并使用此行重新加载数据因为从数组中删除项目而不是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
}
}
答案 1 :(得分:2)
我遇到了同样的问题。问题是我删除了单元格的对象但是当我使用reloadData
的{{1}}方法时,我的tableView
方法没有被调用,因此能够编辑我的单元格不想编辑。真正的修复方法不是调用canEditRowAtIndexPath
方法,而是调用deleteRowsAtIndexPaths
方法。
基本上就是这里发生的事情:
当我致电[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
时:
Nitin说,原始数据没有从reloadData
中删除。因此,这不是解决方案。
当我致电tableView
时:
iOS检测到基础数据和单元格数量之间存在差异(因为我已经删除了基础对象)。结果是崩溃,这也不是解决方案(显然)。
现在进行修复!
当我致电deleteRowsAtIndexPaths
时:
这导致tableView简单地重新加载该单个单元格并且它删除了原始数据。这是解决方案。
不是删除reloadRowsAtIndexPaths
对象,而是尝试删除此时基本上没有任何内容支持的单元格(导致崩溃),只需删除dataSource
对象,然后重新加载dataSource
对象。 indexPath
以下是该方法的一般格式:
tableView
这是我第一次遇到残留原始数据的问题,而这些原始数据并未通过简单地调用- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[myDataSourceArray removeObjectAtIndex:indexPath.row];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
方法来删除。这当然是迄今为止我见过的最优雅的解决方案。
快乐的编码!我希望这会有所帮助。
答案 2 :(得分:0)
- (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];
}
答案 3 :(得分:0)
说到我,我分析如下:
rmaddy
在Nitin Gohel's
回答:
在更新表之前,应始终从数据源中删除数据。
我觉得这是理想的方式。
如果您打算致电reloadData
,则根本没有理由先拨打deleteRowsAtIndexPath
。
这看起来也是正确的。
我分析了歧义,如果我写reloadData
它的crashishing但是一旦我写deleteRowsAtIndexPath
它运作良好。
希望有人会因为其原因等而强调这个问题。
答案 4 :(得分:0)
'removeObjectAtIndex:indexPath'需要一些时间,我怀疑你的 [self.tblView reloadData] 是在早期调用的。我尝试了一个示例代码并发现 [UiTableView beginUpdates] 和 [UiTableView endUpdates] 的成功,如果在重新加载或删除行之前放置一点延迟,您也可以避免崩溃虽然试过了
[tableTable beginUpdates];
[tableArray removeObjectAtIndex:indexPath.row];
[tableTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableTable endUpdates];