CoreData 有一个很棒的工具叫做 NSFetchedResultsController
。此工具允许在 NSManagedObjectContext
中创建或删除符合特定要求 (NSPredicate
) 的对象时接收通知。 每当创建或删除此类对象时,您可以告诉相应的 UITableView
或 UICollectionView
相应地插入/删除行。
对于 UITableView
来说,这相对容易做到。 Apple 确实提供了一个 CoreData Master/Detail 项目模板,其中也包含了所有执行此操作的代码。
对于 UICollectionView
,它有点棘手(因为分组更新是通过处理程序完成的,而不是使用 beginUpdates
/endUpdates
方法)。
此项目使 UICollectionView
(以及更轻松地用于 UITableView
)可以轻松地在 CoreData 项目中使用 NSFetchedResultsController
类:接收来自结果控制器的通知,然后直接将其转发到您的 table 或 collection view。
/* *** Collection View Setup *** */
/* First, how to handle a reload of a cell? */
collectionView.fetchedResultsControllerReloadMode = .handler({ [weak self] cell, object, collectionViewIndexPath, dataSourceIndexPath in
self?.setup(cell: cell as! MyCellType, with: object as! MyObjectType)
})
/* Next, when a cell moves, what to do? Here, we do a move (other solution
* is to delete/insert the cell).
* When a cell is moved, it must be reloaded too. We say we want the
* standard reload mode (the one we have defined above). */
collectionView.fetchedResultsControllerMoveMode = .move(reloadMode: .standard)
/* *** Handling the NSFetchedResultsController notifications *** */
/* We simply forward the methods to the collection view */
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
collectionView.fetchedResultsControllerWillChangeContent()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
collectionView.fetchedResultsControllerDidChange(section: sectionInfo, atIndex: sectionIndex, forChangeType: type)
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
collectionView.fetchedResultsControllerDidChange(object: anObject, atIndexPath: indexPath, forChangeType: type, newIndexPath: newIndexPath)
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
collectionView.fetchedResultsControllerDidChangeContent(endUpdatesHandler: nil)
}
该项目最初由 François Lamboley 在 happn 工作时创建。