G A G A - 1 year ago 48
iOS Question

Cannot animate smoothly a TableView to new cells inserted at the bottom

I have an Swift application that generates information every few seconds and adds it to a ManagedObjectContext.

I have a tableview that implements the NSFetchedResultsControllerDelegate protocol displaying the new values in the screen.

The values always come one by one and they are always inserted at the bottom of the table.

The cells have variable size.

What I need is keep scrolling smoothy to the new inserted cell like it happens in a messaging application.

I have the following code:

func controllerWillChangeContent(controller: NSFetchedResultsController) {

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
self.tableView!.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .None)
self.insertedIndexPath = newIndexPath

func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView!.scrollToRowAtIndexPath(self.insertedIndexPath!, atScrollPosition: .None, animated: animated)

The code works fine, but when there are many rows in the table the animation of the scrolling jumps up and down in every new rows inserted.

Dows anybody know how to make this animation running smooth to the new row?



Answer Source

I have found the solution to my problem. The issue is that I was using auto resizing.

self.tableView!.rowHeight = UITableViewAutomaticDimension
self.tableView!.estimatedRowHeight = 150

The size of my table cells could be very different and the auto resizing always starts sizing the cell to the estimated value. Before adding the new cell the table scrolls automatically to a position calculated based on the estimation. Since the average size could be so variable, the estimated place where the table is scrolled is always wrong which move the scroll up and down like crazy. To solve the problem I set the method:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

I calculate the size right before I set the content of the view. In this way the table calculate the scroll based on the real size of the cells. I hope it helps. GA