简体   繁体   中英

Reorder cells in UICollectionView + NSFetchedResultsController

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:

  1. Change the property you're using in the sort descriptor, so that the new sort result will match the result of the drag and drop operation. Save changes, and NSFetchedResultsController delegate methods will fire. You've changed the order and your fetched results controller will reflect that in its fetchedObjects array.
  2. Don't use 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM