Actually I found a nice method to fix this.. It drove me crazy but look:
So you
- Have a table with expandable content
- Wanna animate a cell’s constraints (height for example)
- And therefore you call tableView.beginUpdates() and tableView.endUpdates()
And soo the table jumps..
As others have said before, it is because updating the tableView makes the tableView Scroll
The solution?
Let’s assume your code looks like this:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell.heightConstraint = 100
UIView.animate(withDuration: 0.15, animations: {
self.view.layoutIfNeeded()
self.tableView.beginUpdates()
self.tableView.endUpdates()
}, completion: nil)
}
Then to fix the jumping issue you have to save the current tableView scroll position until the tableView.endUpdates() being called.
Like this:
var currentScrollPos : CGFloat?
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Force the tableView to stay at scroll position until animation completes
if (currentScrollPos != nil){
tableView.setContentOffset(CGPoint(x: 0, y: currentScrollPos!), animated: false)
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell.heightConstraint = 100
UIView.animate(withDuration: 0.15, animations: {
self.currentScrollPos = self.tableView.contentOffset.y
self.view.layoutIfNeeded()
self.tableView.beginUpdates()
self.tableView.endUpdates()
self.currentScrollPos = nil
}, completion: nil)
}