删除 UITableView 中的行时出错

Posted

技术标签:

【中文标题】删除 UITableView 中的行时出错【英文标题】:Error deleting row in UITableView 【发布时间】:2012-01-21 15:12:53 【问题描述】:

尝试从 UITableView 中删除一行时出现此错误。如果我删除 tableview 中的最后一行,则不会出错并且一切正常,但任何其他行都会引发异常。有人可以告诉我我在这里做错了什么吗?任何帮助将不胜感激!

错误:

'无效更新:第 1 节中的行数无效。更新 (2) 后现有节中包含的行数必须等于更新前该节中包含的行数 (2),加上或减去从该节插入或删除的行数(0 插入,1 删除),加上或减去移入或移出该节的行数(0 移入,0 移出)。'

代码

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

    //1. clear existing URL's
    NSURL *urlToDelete = nil;

    //2. If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) 
        NSInteger row = [indexPath row];
        urlToDelete = [documentURLs objectAtIndex:row];
        //[documentURLs removeObjectAtIndex:row];      
    
    //3. update the tableview on the fly without reloading the data
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                     withRowAnimation:UITableViewRowAnimationFade];

    //4. get the location of the files
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *pathToDocumentsDirectory = [paths objectAtIndex:0];

    //5.setup file manager
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    BOOL fileExists = [fileManager fileExistsAtPath:pathToDocumentsDirectory];
    NSLog(@"Path to file: %@", pathToDocumentsDirectory);        
    NSLog(@"File exists: %d", fileExists);
    NSLog(@"Is deletable file at path: %d", [fileManager isDeletableFileAtPath:pathToDocumentsDirectory]);

    //6. remove if matches
    if (urlToDelete) 
        BOOL success = [fileManager removeItemAtURL:urlToDelete error:&error];
        if (!success) NSLog(@"Error: %@", [error localizedDescription]);
    

【问题讨论】:

尝试检查一下 - 可能是您的问题:***.com/questions/5043729/… //3. update the tableview on the fly without reloading the data [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 仅在成功为真时才尝试放入第六步。您的模型和表格视图中的行之间存在不一致 【参考方案1】:

您必须分三个阶段更新表。

1) 处理你的模型

[documentURLs removeObjectAtIndex:row];

2) 处理表格的动画

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

3) 处理您的文件更新(也许之前可以完成,因为您可能在文件删除时出错)

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

   NSURL *urlToDelete = nil;

   if (editingStyle == UITableViewCellEditingStyleDelete) 
       NSInteger row = [indexPath row];
       urlToDelete = [documentURLs objectAtIndex:row];
       [documentURLs removeObjectAtIndex:row]; // you need to update your model

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

       // do stuff to update the file here
    

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

    NSURL *urlToDelete = nil;

    if(editingStyle == UITableViewCellEditingStyleDelete) 
        NSInteger row = [indexPath row];
        urlToDelete = [documentURLs objectAtIndex:row];

        // do stuff to update the file here...

        if(success)
        
            [documentURLs removeObjectAtIndex:row]; // you need to update your model

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

注意。如果从模型中删除项目并且模型计数等于 0,则必须注意。在这种情况下,您必须删除整个部分。

希望对你有帮助。

附:检查代码,因为我没有使用 XCode 编写代码

【讨论】:

这就是诀窍,你的第二个建议指出了我正确的方向。谢谢你的帮助,你让我开心!【参考方案2】:

您是否需要像示例那样在开始和结束更新中包装删除

[self.wallsTable beginUpdates]; //<<<<<<<<<<<<<<<<<<<<<<<<<
NSArray *paths = [NSArray arrayWithObject: deleteView.cellPath];
[self.wallsTable deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop];
[[self.wallEntries objectAtIndex:[deleteView.cellPath section]] removeObjectAtIndex:[deleteView.cellPath row]];
[self.wallsTable endUpdates]; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

所以你需要从表格中删除,并从这些单元格中的任何内容中删除

【讨论】:

@carbonbasednerd - 我已经将它们存储在数组中,但感谢您的建议。 @Flex_Addicted - 我在发帖前尝试过这种方法,但没有什么不同,但感谢您的建议。 我不确定我是否理解您的建议,我试图采纳您的建议并将其应用于我的 BOOL 但仍然没有运气。如果它是最后一行,它工作得很好,而不是在中间。还有其他想法吗? 您是否尝试在第 3 点之前使用开始更新并在第 6 点之后使用 endupdates 关闭它。您还确定当您单步执行代码时该 url 被正确删除了吗?因为它是否正确匹配要删除的单元格与要删除的 url? 是和是的更新和是的 URL 匹配。我完全被这个弄糊涂了【参考方案3】:

第 3 步应该在第 2 步的 if 块内 - 只有在 editingStyle 为删除时才执行删除。 否则,您将在不调整其他数据结构的情况下从表中删除行。

//2. If row is deleted, remove it from the list.
if (editingStyle == UITableViewCellEditingStyleDelete) 
    NSInteger row = [indexPath row];
    urlToDelete = [documentURLs objectAtIndex:row];
    [documentURLs removeObjectAtIndex:row];      
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]   
                     withRowAnimation:UITableViewRowAnimationFade];

【讨论】:

以上是关于删除 UITableView 中的行时出错的主要内容,如果未能解决你的问题,请参考以下文章

添加/删除 UITableView 行时如何防止文本字段变空?

为啥我的 UITableView 在插入或删除行时会“跳跃”?

为啥删除 UITableView 行时会出现错误?

尝试从 UITableView 中删除行时断言失败

选择 UITableView 中的行时如何清除文本字段?

使用 CoreData 删除行时 UITableView 崩溃