Keeping correct content offset after insertion of new row(s)

Hi all,


So I am having this problem for a few months now, and I asked it on stackoverflow already:


https://stackoverflow.com/questions/54281617/bounce-occurs-when-changing-rows


If you clone this project, you can directly run it and see the problem described below for yourself (if you scroll a little bit after you see the rows): https://github.com/Jasperav/FetchResultControllerGlitch


I am using a UITableView with performBatchUpdates to process new rows. When I insert a new row at the top, it sometimes glitches (as seen in the link above, it does not glitch when starting the app up and wait). I don't want it to glitch. I want the same behaviour as whatsapp (assuming they use a UITableView/UICollectionView): When a new message comes in and the user has scrolled a little upward to read older messages, the messages the user is seeing do not change (no bounce, glitches). I just can not get it to work.


I already tried: CATransaction, UIView.performWithoutAnimation, layoutSubviews and layoutIfNeeded. Different calculations do not help. I checked ofcourse other answers of this community and stackoverflow, nothing is working for me...


This is the most important part I think. It tries to calculate the new content offset:


public func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {

let currentSize = tableView.contentSize.height


UIView.performWithoutAnimation {

tableView.performBatchUpdates({

tableView.insertRows(at: inserts, with: .automatic)

})

inserts.removeAll()

self.view.layoutIfNeeded() // Tableview scrolls weirdly after the correction, this call will omit that.

let newSize = tableView.contentSize.height

let correctedY = tableView.contentOffset.y + newSize - currentSize


print("Will apply an corrected Y value of: \(correctedY)")

tableView.setContentOffset(CGPoint(x: 0,

y: correctedY),

animated: false)

print("Corrected to: \(correctedY)")

}

}