【问题标题】:At canEditRowAtIndexPath Method, reloadData of UITableView not work properly?在 canEditRowAtIndexPath 方法中,UITableView 的 reloadData 不能正常工作?
【发布时间】:2013-08-23 04:39:43
【问题描述】:

在我的应用程序中,我在从 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];  
}

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

【问题讨论】:

  • 发布您的numberOfRowsInSection 方法。问题 - 在您的 commitEditingStyle 方法中,为什么要调用 updateListOfSoundsFile?您已经通过删除一个对象更新了listOfSounds。从数组中删除对象后,只需调用deleteRowsAtIndexPaths 从表中删除一行。还要验证您对deleteSoundFileAudioTableWhereMainID 的调用实际上是从数据库中删除一行。

标签: iphone ios objective-c uitableview


【解决方案1】:

您还需要从 tableview 中删除原始数据,然后才能从数组中删除项目并使用此行重新加载数据,因为从数组中删除项目而不是 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,则完全没有理由先致电deleteRowsAtIndexPath:。此解决方案可能有效,但它隐藏了一些其他问题。
  • 那么请指导我们什么是正确的解决方案先生,请用正确的解决方案回答。谢谢
  • @rmaddy-先生,如果您有其他最佳解决方案,请指导我们,以提高知识。谢谢
【解决方案2】:

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

基本上这是发生了什么:

当我打电话给reloadData 时: 正如 Nitin 所说,原始数据并未从 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 方法无法删除的残留原始数据的问题。这无疑是迄今为止我见过的最优雅的解决方案。

编码愉快!我希望这会有所帮助。

【讨论】:

    【解决方案3】:
    - (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]; 
    }
    

    【讨论】:

    • 请解释一下这是如何解决问题的? updateListofSoundsFile 方法已经调用了reloadData
    【解决方案4】:

    说到我,我分析如下:

    正如rmaddyNitin Gohel's 上评论的回答:

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

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

    2. 如果你要打电话给reloadData,完全没有理由先打电话给deleteRowsAtIndexPath

      这看起来也是正确的。

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

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

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-01
        • 2012-11-08
        • 1970-01-01
        • 1970-01-01
        • 2015-06-29
        相关资源
        最近更新 更多