Smooth UITableView animation when deleting a section

TL; DR

When deleting a section in a UITableView, when the scroll offset is somewhere in the middle of the table, the animation stream looks like this:

  • Offset content is set to (0,0) right away (no animation, just pops up)
  • Section disappears beautifully

I would like to make this stream of animation a little better - disappear into the section and only then (or at the same time smoothly) scroll the "dead zone" of the table up.

A bit more explanation.

I use NSFetchedResultsController as a data source for a UITableView to display rows and update the table when changes occur in NSManagedObjectContext - like this (I removed the unrelated code) -

- (void)controller: (NSFetchedResultsController *)controller didChangeObject: (id)anObject atIndexPath: (NSIndexPath *)indexPath forChangeType: (NSFetchedResultsChangeType)type newIndexPath: (NSIndexPath *)newIndexPath { UITableView *tableView = self.tableController.tableView; switch(type) { .... NSFetchedResultsChangeDelete:[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; break; ... } } 

I have all the controllerWillChangeContent and controllerDidChangeContent , the result of this code is that if all the rows in a specific section are deleted - the section is also deleted.

The problem (as I pointed out in the tl; dr section) is that the animation does not work properly - If the section is deleted while scrolling halfway in the remote section, the contents of the scroll change immediately and the section disappears, which looks pretty broken.

Has anyone stumbled upon such a situation? I am sure I can narrow it down to a common problem without using the NSFetchedResultsController, which uses the code that I am currently using.

I would love to add more information if necessary.

Thanks!

Update 1

So, after I played a little with contentOffset manually, I can get something partially working while executing this thread -

  • When NSFetchedResultsController calls controllerWillChangeContent , I save the UITableView contentOffset (until beginUpdates )
  • When the controllerDidChangeContent call is called, and right after the endUpdates call endUpdates I save the table's contentOffset (this is the offset that was not animated).
  • I will go back to the original content that I saved in the first part, and use [tableView setContentOffset:offsetAfterEndUpdates animated:YES] to go to the new offset

This may not be the best solution / Apple.

+4
source share
3 answers

A UITableViewDelegate also conforms to the UIScrollViewDelegate protocol, so you can defer the deletion action of this section to

 - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { // try to perform your action here, // for instance you could re-attach your NSFetchedResultController delegate here } 
0
source

One approach that works (at least in my experience) is: a) deleting a section and b) not deleting individual rows.

For reference, consider TLIndexPathUpdates initializer in TLIndexPathTools . It calculates batch updates, and I think it works well for the scenario you described.

0
source

Good!

So, after intensive digging, I found that the problem is in my code (for example, I was commented right after the publication). It was pretty hard to find, but somewhere between beginUpdates and endUpdates I change the presentation of the UITableView footer, which is useless with the contentOffset animation.

So this is my fault, not Apple.

Thanks for the help of Jonathan Cichon!

0
source

Source: https://habr.com/ru/post/1485387/


All Articles