Anders Anders - 7 months ago 81
Swift Question

How to remove section header when moving last row from a section

I have an UITableView that is connected to core data. The tableview has dynamic cells and groups the rows into sections (categories).

I can move the rows by dragging between the sections and this works fine with core data except when I the drag a row and the section becomes empty. I would like the section header to disappear but it stays as a header with no rows inside. Then if I try to drag a row back I get an error.

I have implemented the NSFetchedResultsController functions for didChangeObject and didChangeSection. However when dragging the rows I figured out that I have to set the delegate for fetchedResultsController to nil.

Here is the part of the code that handles move.

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {

// Create array of fetched items from the stack
var items = fetchedResultsController.fetchedObjects! as! [Item]

// Convert the index paths to row number in the table.
let destinationRow = rowAtIndexPath(destinationIndexPath)
var sourceRow = rowAtIndexPath(sourceIndexPath)

// Source row has to be reduced by one if it was moved to lower section because tableview is counting the row twice, once in the new section and once as the row index in the old section.
if sourceIndexPath.section > destinationIndexPath.section {
sourceRow -= 1
}

let newCategory = fetchedResultsController.sections![destinationIndexPath.section].name

// Get the item of from the source index path and update the category
let item = fetchedResultsController.objectAtIndexPath(sourceIndexPath) as! Item
item.category = newCategory

// Do not trigger delegate methods when changes are made to core data
fetchedResultsController.delegate = nil

// Move the item in core data
items.removeAtIndex(sourceRow)
items.insert(item, atIndex: destinationRow)


do {
try coreDataStack.context.save()
} catch {
fatalCoreDataError(error)
}

fetchedResultsController.delegate = self
}


I have not found any question that answers this, especially not in Swift.
Any help to solve this is much appreciated.

Answer

Why do you need to set the delegate to nil? If this is because of an error that would indicate you have implemented something incorrectly.

Answering your original question: Since you are using an NSFetchedResultsController then the section will be removed automatically by the NSFetchedResultsControllerDelegate method controller(_, didChangeSection, atIndex, forChangeType)

The real question is, why did you set the delegate to nil?

Comments