I have a tableView in a Swift iOS app that allows the user to re-order the rows. An Edit button is tapped, rows can be re-ordered or deleted, and the Edit button (which now reads Done) is re-tapped to complete the process.
If I simply use the tableView:moveRowAtIndexPath:toIndexPath: method, it works as described above and the table shows the re-ordered rows correctly when Done is tapped. But it doesn't remember the new order when returning to the table, so I added a new "position" variable (Int) in core data and I have made my table sort itself based on that.
My problem is that after a user has moved a row and clicks Done, the table immediately re-orders itself back to how it was before. So it is using the old (original) position variables in core data, before my code can properly capture the new order and re-write it to core data.
Is there a way to make this new order get captured when Done is clicked before the table reloads?
Here is my code that handles the move:
func tableView(tableView: UITableView!, moveRowAtIndexPath sourceIndexPath: NSIndexPath!, toIndexPath destinationIndexPath: NSIndexPath!) {
}
And here is my code that is called when Done is pressed. I go through each row of my table and re-assign the person's position variable in core data based on it's new row:
for currentIteration in 0..<tableView.numberOfRowsInSection(0) {
var indexPathForCurrentIteration = NSIndexPath(forRow: currentIteration, inSection: 0)
let personAtCurrentIndexIteration = fetchedResultsController.objectAtIndexPath(indexPathForCurrentIteration) as PersonModel
personAtCurrentIndexIteration.position = indexPathForCurrentIteration.row
println("\(personAtCurrentIndexIteration.name) has a position value of \(personAtCurrentIndexIteration.position)")
(UIApplication.sharedApplication().delegate as AppDelegate).saveContext()
tableView.reloadData();
}
The above is called when the Done button is pressed, but I also tried calling it within the moveRowAtIndexPath method without success (same result - it reloads the old order of the table when Done is pressed). I have also tried commenting out reloadData without success.
I think my problem might lie in the fact that the above is not capturing the new row order, but instead still gets the old row order. If that is the case, then I don't know the simplest way to make it "wait" to get the new row order.
A longer workaround that I started considering would be to capture the moved row's initial and final row value, and based on that update the remaining rows' values accordingly. Some of that code is below but I stopped since I figured there is likely a smarter way.
if((sourceIndexPath.row > indexPathForCurrentIteration.row) && (destinationIndexPath.row > indexPathForCurrentIteration.row)) {
//if the moved row was ahead of this row before AND after the move, do nothing (don't change this row's position value)
//println("\(personAtCurrentIndexIteration.name)'s position was unchnaged")
} else if((sourceIndexPath.row > indexPathForCurrentIteration.row) && (destinationIndexPath.row < indexPathForCurrentIteration.row)) {
//if the moved row was ahead of this row before BUT behind it after the move, then this row's position value needs to be bumped up one number
personAtCurrentIndexIteration.position = indexPathForCurrentIteration.row+1
//Etc...
Thanks in advance for any help you can provide.