我有一个由NSFetchedResultsController支持的表视图。 情况如下。 我已经实现了“轻扫删除”一行。调用NSFetchedResultsController的委托方法和表视图的委托方法。但问题是,我不想删除核心数据实体,我只想标记它的布尔标志,因为我在应用程序的其他部分需要这个实体,并希望表视图删除带动画的行。但是,根据错误消息,它与逻辑相反,如果您要更新实体,更新行,而不是删除它。 有没有优雅的方法来实现它?或者唯一的选择是重新加载表格? 实施滑动删除
- (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移出)。 with userInfo(null)
答案 0 :(得分:4)
在您提供给FRC的获取请求中,将此布尔值包含在谓词中。例如,[NSPredicate predicateWithFormat:@"shouldDisplay = YES"]
。然后,只要您想删除特定对象,只需将您的shouldDisplay(或任何您调用它)设置为NO,您将收到controller:
didChangeObject:
的{{1}}更改类型的FRC委托回调。在此回调中,您将执行以下操作。
NSFetchedResultsChangeDelete
您的对象将保留在核心数据中,但由于您在布尔标志上的谓词,它将从此特定表视图中过滤掉。
编辑:您还需要实现两个FRC委托方法,以通知您的表视图开始和结束更新。这将纠正您收到的错误。像这样:
NSIndexPath *indexPath = [controller indexPathOfObject:anObject];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
答案 1 :(得分:0)
我无法获得Pat Goley的解决方案,但也许我没有正确实施它。经过一些实验,我提出的解决方案包含在一个回调方法中:
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle != .Delete { return }
let obj = fetchedResultsController.objectAtIndexPath(indexPath) as! Entity
obj.needsDeletion = true
try! managedObjectContext.save()
try! fetchedResultsController.performFetch()
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
这样做的缺点是必须调用performFetch()
,但没有它,它就会崩溃。对于非常大的记录集,类似于Pat的方法可能是最好的。