GitHunt
FR

Frizlab/CollectionAndTableViewUpdateConveniences

A group of conveniences for UITableView and UICollectionView to allow easier updates in coordination with NSFetchedResultsController

= CollectionAndTableViewUpdateConveniences
François Lamboley francois.lamboley@happn.com

:happn: https://happn.com
:frizlab: https://github.com/Frizlab

image:https://img.shields.io/badge/platform-iOS-lightgrey.svg?style=flat[Platforms] link:https://swift.org/package-manager/[image:https://img.shields.io/badge/SPM-compatible-E05C43.svg?style=flat[SPM Compatible]] link:License.txt[image:https://img.shields.io/github/license/happn-app/CollectionAndTableViewUpdateConveniences.svg[License]] link:{happn}[image:https://img.shields.io/badge/from-happn-0087B4.svg?style=flat[happn]]

Easily handle NSFetchedResultsController updates in a UITableView or a UICollectionView.

== What’s this for?
CoreData has a wonderful tool called NSFetchedResultsController.
This tool allows notifications when an object matching a specific set of requirements (NSPredicate) is created or deleted in an NSManagedObjectContext.
Whenever such objects are created or deleted, you can tell a corresponding UITableView or UICollectionView to insert/delete the corresponding rows.

For a UITableView, it is relatively easy to do.
Apple does provide a CoreData Master/Detail project template which has all of the code to do it too.

With a UICollectionView, it is a bit more tricky (because grouped updates are done via a handler instead of using the beginUpdates/endUpdates methods).

This project makes it easy for a UICollectionView (and easier for a UITableView) to use the NSFetchedResultsController class in a CoreData project:
receive the notifications from the results controller and forward them to your table or collection view directly.

== Example of use
[source,swift]

/* *** 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 forward the methods to the collection view. */
func controllerWillChangeContent(_ controller: NSFetchedResultsController) {
   collectionView.fetchedResultsControllerWillChangeContent()
}
func controller(_ controller: NSFetchedResultsController, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
   collectionView.fetchedResultsControllerDidChange(section: sectionInfo, atIndex: sectionIndex, forChangeType: type)
}
func controller(_ controller: NSFetchedResultsController, 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) {
   collectionView.fetchedResultsControllerDidChangeContent(endUpdatesHandler: nil)
}

== Installation
The project is SPM-compatible.

You can also copy the two UICollectionView extensions and the UITableView extension in your project.

== Credits
This project was originally created by {frizlab}[François Lamboley] while working at {happn}[happn].