9

I need to expand/collapse a section of UITableView. I do this by calling reloadSections:withRowAnimation: and returning 0 from tableView:numberOfRowsInSection: if the section is supposed to be collapsed.

It works fine except for one case. If the table view is scrolled all the way down and content size decreases after collapse, it ends up being scrolled beyond maximum offset. Now instead of scrolling in place with animation it just snaps there, which looks ugly:

enter image description here

Here's what I have tried:

  1. Wrapping reloadSections:withRowAnimation: in beginUpdates/endUpdates:

    tableView.beginUpdates()
    tableView.reloadSections(indexSet, withRowAnimation: .Automatic)
    tableView.endUpdates()
    

    That did not help.

  2. Wrapping reloadSections:withRowAnimation: in CATransaction with completion block, calculating the scroll distance within it and scrolling table view with animation:

    CATransaction.begin()
    CATransaction.setCompletionBlock {
        // tableView.contentSize is incorrect at this point
        let newContentOffset = ... // calculated value is not correct
        tableView.setContentOffset(newContentOffset, animated: true)
    }
    
    tableView.beginUpdates()
    tableView.reloadSections(indexSet, withRowAnimation: .Automatic)
    tableView.endUpdates()
    CATransaction.commit()
    

How do I make sure the table view does not jump?

Andrii Chernenko
  • 9,873
  • 7
  • 71
  • 89
  • I think I am also sort of facing same issue. The gif is sort of hard to comprehend what you saying. Any way you can create a short clip maybe? Would give much clear idea. – rohan-patel Jan 22 '16 at 18:22
  • @rohan-patel replaced the demo, this one should demonstrate the problem better. – Andrii Chernenko Jan 24 '16 at 10:31
  • [UITableView jumping to top on endUpdates while typing inside a cell on iOS 8 auto height](http://stackoverflow.com/q/28917923/2301450) – vaultah Jul 27 '16 at 06:25

1 Answers1

6

I ran into this issue when using custom headers in collapsible sections. I did solve it by implementing.

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat 
Hugo Perez
  • 481
  • 8
  • 10