使用 NSFetchedResultsController 滑动以删除表格中的单元格

Posted

技术标签:

【中文标题】使用 NSFetchedResultsController 滑动以删除表格中的单元格【英文标题】:Swipe to Delete a Cell in a Table using NSFetchedResultsController 【发布时间】:2013-10-21 15:54:23 【问题描述】:

我之前有一个工作实现,其中我有一个 TableViewController,我按下 ADD 按钮,它会打开另一个视图控制器,让用户可以将文本添加到字段 - 这反过来又将该信息添加到实体和属性中我可以在表格视图中显示它。实现以下方法,我可以滑动删除一行成功:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    return YES;


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


    if (editingStyle == UITableViewCellEditingStyleDelete)
    
        [self.managedObjectContext deleteObject:[self.transactions objectAtIndex:indexPath.row]];
        [self.transactions removeObjectAtIndex:indexPath.row];
        [self.tableView reloadData];

        NSError *error = nil;
        if (![self.managedObjectContext save:&error])
        
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
            [self.tableView reloadData];
        
    


现在,我成功地实现了 NSFetchedResultsController 以允许添加和获取信息的相同功能,但更安全。我现在无法弄清楚的是如何实际实现相同的滑动删除功能。

我添加了:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    return YES;

我添加了这个,“滑动”手势无法删除单元格。

在数据源的 NSFetchedReusltsController 代码中,我有:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath 

    UITableView *tableView = self.tableView;

    switch(type) 

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray
                                               arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray
                                               arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    

连同所有必需的方法,但滑动删除操作不起作用。

对此的任何想法都会非常有帮助。

【问题讨论】:

创建一个使用core data的空项目,看看FRC和table view delegate方法的实现,应该和你需要的很相似。 谢谢丹 - 我做到了,并通过下面的答案,我得到了它的工作。非常感谢您的回答。 【参考方案1】:

要从表中删除一行,您只需删除相应的 核心数据对象:

if (editingStyle == UITableViewCellEditingStyleDelete)

    [self.managedObjectContext deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

    NSError *error = nil;
    if (![self.managedObjectContext save:&error]) 
        // handle error
    

就是这样,特别是您不需要调用reloadData。 删除对象会触发 获取结果控制器委托方法,并更新表视图。

现在从您的代码看来,您有一个数据源数组self.transactions。 这是错误的,你应该删除它。所有数据源方法都必须获取信息 直接从获取的结果控制器中。

【讨论】:

嗨,马丁 - 这真是太棒了。这就像一种享受,非常感谢。事实上,自我交易是在我实现 NSFetchedResultsController 之前进行的,并且效果很好。我想我在想,也许 didChangeObject: forChangeType: newIndexPath: 中的 switch 语句是这段代码必须去的地方,等等。你是那个人,我真的很感激!

以上是关于使用 NSFetchedResultsController 滑动以删除表格中的单元格的主要内容,如果未能解决你的问题,请参考以下文章

核心数据保存竞争条件错误

在 Swift 3 中难以配置 NSFetchedResultsController

为啥 beginUpdates/endUpdates 会重置表视图位置以及如何阻止它这样做?

测试使用

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?