Moving rows with NSFetchedResultsController (Swift)

175 Views Asked by At

Why exactly doesn't this work? When the tableview reloads data, the objects move to their original position

override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    var objects = myFetchRC.fetchedObjects!

    let object = myFetchRC.object(at: sourceIndexPath)
    objects.remove(at: sourceIndexPath.row)
    objects.insert(object, at: destinationIndexPath.row)

    CoreDataStack.shared.saveContext()

    tableView.reloadData()


}

EDIT: moving the reload data function to after the save context does not solve the issue, unfortunately.

2

There are 2 best solutions below

0
pietrorea On

Try swapping tableView.reloadData() and CoreDataStack.shared.saveContext().

Core Data only fully commits your changes when you save the managed object context, so when the tableView reloads, you are likely still getting the old ordering.

0
AudioBubble On

I came up with an extremely knuckle-headed solution.

First a new sort descriptor, a Double attribute called "index":

myFetch.sortDescriptors = [NSSortDescriptor(key: "tripName", ascending: true), NSSortDescriptor(key: "index", ascending: true)]

Every time a new object is created the index is incremented in an ascending order. Then in the moveRowAt function I added this:

override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    
    if sourceIndexPath > destinationIndexPath{
        myFetchRC.object(at: sourceIndexPath).index = myFetchRC.object(at: destinationIndexPath).index - 0.01
    } else{
        myFetchRC.object(at: sourceIndexPath).index = myFetchRC.object(at: destinationIndexPath).index + 0.01
    }
    
    CoreDataStack.shared.saveContext()
    tableView.reloadData()
    
}

This is an extremely ugly solution, and I'm sure it's prone to bugs, but it seems to work. If someone else has the proper solution please let me know!!