删除tableview中的一行,而不删除Core Data Entity [英] Deleting a row in tableview without deleting Core Data Entity

查看:149
本文介绍了删除tableview中的一行,而不删除Core Data Entity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由NSFetchedResultsController支持的表视图。
情况如下。
我已经实现了滑动删除一行。 NSFetchedResultsController的委托方法和表视图的委托方法被调用。但事情是,我不想删除一个核心数据实体,我只想标记其布尔标志,因为我需要这个实体在应用程序的其他部分,并希望表视图删除行与动画。但是,根据错误消息,它是违反逻辑,如果你正在更新一个实体,更新一行,不删除它。
有没有任何优雅的方式来实现呢?或者唯一的选项是重新载入表格?

执行滑动即可删除

I have a table view backed by NSFetchedResultsController. The situation is as follows. I have implemented "swipe to delete" a row. Delegate methods of NSFetchedResultsController and those of table view's are called. But the thing is, I don't want to delete a Core Data Entity, I just want to mark its boolean flag since I need this entity in other parts of application, and want table view to delete row with animation. However, according to error messages it is against logic like if you are updating an entity, update a row, not delete it. Is there any elegant way to achieve it? Or the only option is reload the table?
Implementation of swipe to delete

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

   if (editingStyle == UITableViewCellEditingStyleDelete) {
      Issue *issue = [self.fetchedResultsController objectAtIndexPath:indexPath];
      [issue setHasBeenDeleted:[NSNumber numberWithBool:YES]];
      [issue setPurchased:[NSNumber numberWithBool:NO]];
      [self.managedObjectContext saveToPersistentStore:nil];
   }
}

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

...

        case NSFetchedResultsChangeUpdate:

                             [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
        break;

NSFetchedResultsControllerDelegate

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
  [self.tableView endUpdates];
}

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}

错误讯息


CoreData:错误:严重的应用程序错误。在对-controllerDidChangeContent:的调用期间,NSFetchedResultsController的委托捕获了异常。无效更新:部分0中的行数无效。更新(5)后现有部分中包含的行数必须等于更新前该部分中包含的行数(4),加或减数字从该部分插入或删除的行(插入0个,删除1个)以及移入或移出该部分的行数(0移入,0移出)。

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)


推荐答案

在获取请求中,这个布尔值作为您的谓词的一部分。例如, [NSPredicate predicateWithFormat:@shouldDisplay = YES] 。然后每当你想要删除特定的对象,只要设置你的shouldDisplay(或任何你称之为),你会收到一个FRC委托回调为控制器:
didChangeObject:
NSFetchedResultsChangeDelete 更改类型。在此回调中,您将执行以下操作。

In the fetch request you are giving to your FRC, include this boolean value as a part of your predicate. For example, [NSPredicate predicateWithFormat:@"shouldDisplay = YES"]. Then whenever you want to remove are particular object, just set your shouldDisplay (or whatever you call it) to NO, and you will receive an FRC delegate callback for controller: didChangeObject: with a NSFetchedResultsChangeDelete change type. In this callback, you will do the following.

NSIndexPath *indexPath = [controller indexPathOfObject:anObject];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

您的对象将保留在核心数据中,但会从此特定表视图中过滤掉您的谓词的布尔标志。

Your object will remain in core data, but it will be filtered out of this particular table view because of your predicate on the boolean flag.

编辑:您还需要实现两个FRC委托方法通知您的表视图开始和结束更新。这将纠正您收到的错误。像这样:

You also need to implement two of the FRC delegate methods to notify your table view to begin and end updates. This will correct the error you are receiving. Like so:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {

    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {


    [self.tableView endUpdates];
}

这篇关于删除tableview中的一行,而不删除Core Data Entity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆