I have a UICollectionView which displays entities from CoreData with NSFetchedResultsController. As you can see on the screenshot, the user can select multiple cells which get marked with a border.
My model has basically just a string and a boolean for handling selection via the UICollectionView.
var url: String
var selected: Bool
var section:Section
I have implemented func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
in order to support reordering of the UICollectionViewCells
. The drag and drop operation works fine, but I am struggling with saving the moved items to CoreData. Do I have to add a position
property to my model?
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
var sourceArray = self.fetchedResultController.fetchedObjects
let item = sourceArray?.remove(at: sourceIndexPath.item)
sourceArray?.insert(item!, at: destinationIndexPath.row)
coreData.saveContext()
}
I tried to modify fetchedResultsController.fechtedObjects
directly, which is not wokring since this property is read-only. What's the best way to do drag&drop with UICollectionView
and NSFetchedResultsController
.
EDIT:
Initial sorting of the UICollectionView
is based on an index property in the Section
model. Currently there is just this sorting key for the sections, nothing for items within the sections.
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "section.index", ascending: false)]
let resultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath:"section.name", cacheName: nil)
As you've found, you can't just tell NSFetchedResultsController
to change the order of objects in its fetchedObjects
array. That array is sorted based on your sort descriptor, and is read-only.
So you have two possible options:
NSFetchedResultsController
delegate methods will fire. You've changed the order and your fetched results controller will reflect that in its fetchedObjects
array.NSFetchedResultsController
, just do a fetch and save the results in your own array. Re-order the items in your own array but don't change anything that Core Data cares about.