My UITableView
is scrolling up once I add a new comment to CoreData. NSFetchedResultsController knows about it, puts this comment at the bottom of the table, and scroll table to top. Is it normal?
My example:
Just before I add a comment:
Just after I add a comment (not expected behavior):
It should be just like this (after I swipe it by hand manually):
This may be connected with following situation:
This is sort descriptor of my NSFetchedResultsController
:
NSSortDescriptor(key: "createdAt", ascending: false) //from the latest to the oldest
But I need to display my comments for reversed index paths (the latest are at the very bottom). In other words, everywhere when I need to use indexPath
I use:
private func reversedIndexPathForIndexPath(indexPath: NSIndexPath) -> NSIndexPath {
return NSIndexPath(forRow: fetchedResultsController.fetchedObjects!.count - indexPath.row - 1, inSection: 0)
}
NSFetchedResultsControllerDelegate
:
//MARK: - NSFetchedResultsControllerDelegate
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
if let newIndexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([reversedIndexPathForIndexPath(newIndexPath)], withRowAnimation: .Fade)
}
case .Delete:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([reversedIndexPathForIndexPath(indexPath)], withRowAnimation: .Fade)
}
case .Update:
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([reversedIndexPathForIndexPath(indexPath)], withRowAnimation: .Fade)
}
case .Move:
if let indexPath = indexPath, let newIndexPath = newIndexPath {
tableView.deleteRowsAtIndexPaths([reversedIndexPathForIndexPath(indexPath)], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([reversedIndexPathForIndexPath(newIndexPath)], withRowAnimation: .Fade)
}
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
Is it connected to my problem?
Edited answer:
I was able to reproduce this glitch with the following steps:
UITableView
with its rowHeight
set to UITableViewAutomaticDimension
and non-zero estimatedRowHeight
.The source of this behavior needs additional investigation.
For now the only solution is not to use UITableViewAutomaticDimension
and return row heights from tableView:heightForRowAtIndexPath:
.
By the way, implementation of inverted index paths has one significant flaw. When FRC calls it's delegate method controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
, all deletion index paths belongs to pre-change data set, and all insertion index paths - to post-change one. When you are in-beetween controllerWillChangeContent:
and controllerDidChangeContent:
, fetchedResultsController.fetchedObjects
will contain post-change data set, i suppose (needs to be checked, though).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With