5

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

例如:

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

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

由于未捕获的异常“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];  
}

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

4

5 回答 5

5

您还需要从表视图中删除原始数据,然后从数组中删除项目并使用此行重新加载数据,因为从数组中删除项目而不是表视图。

[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
    }
}
于 2013-08-23T04:59:09.397 回答
2

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

基本上这是发生了什么:

当我打电话时:原始数据并未像 Nitin 所说reloadData的那样被删除。tableView因此,这不是解决方案。

当我打电话时deleteRowsAtIndexPaths:iOS 检测到底层数据和单元格数量之间存在差异(因为我已经删除了底层对象)。结果是崩溃,这也不是解决方案(显然)。

现在修复!

当我打电话时reloadRowsAtIndexPaths:这导致 tableView 简单地重新加载该单个单元格并且它摆脱了原始数据。这就是解决方案。

而不是删除dataSource对象,然后尝试删除此时基本上没有任何支持的单元格(这会导致崩溃),只需删除对象,dataSource然后重新加载indexPathtableView

这是该方法的一般格式:

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

这是我第一次遇到仅通过调用该reloadData方法无法删除的残留原始数据的问题。这无疑是迄今为止我见过的最优雅的解决方案。

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

于 2013-10-30T02:44:09.280 回答
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]; 
}
于 2013-08-23T04:52:55.710 回答
0

说到我,我分析如下:

正如rmaddyNitin Gohel's答案的评论:

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

    我觉得这是最理想的方式。

  2. 如果你要打电话reloadData,根本没有理由先打电话deleteRowsAtIndexPath

    这看起来也是正确的。

我分析了歧义,如果我写reloadData它会崩溃,但一旦我写 deleteRowsAtIndexPath它就很好用。

希望有人会强调这个问题的原因等。

于 2014-08-27T10:57:24.380 回答
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];
于 2017-01-18T11:35:55.370 回答