I have a weird animation issue based on two independent events:
1) Bouncing UICollectionView to the top (as in the video below)
2) Serially inserting sections (using DifferenceKit)
I've already verified that this has nothing to do with Attributes calculating in my custom UICollectionFlowLayout.
Does anyone know how to solve it?
Here is a Video of the issue
UPD:
Here is some code, updating collection:
private func updateCollection() {
let changeset = StagedChangeset(source: self.previousStage, target: self.viewModels)
// Guarantee that updateCollection calls from background
DispatchQueue.main.sync {
self.delegate?.refreshCollection(with: changeset, update: { collection in
self.viewModels = collection
self.previousStage = collection
})
}
}
Well, since no one suggested a solution, I can offer two solutions that I've researched, with their pros and cons
The problem is detected only when collectionView.contentOffset.y is negative and section inserts.
While we scrolling / holding any collection our main thread RunLoop has tracking mode and if iOS receive notification about section inserting, this operation is performed in common mode. It updates immediately, possibly neglecting smoothness. The solution is to use
RunLoop.current.perform(inModes: [.default]) { /* Perform updates */ }
The main minus is an escaping block and consequently asynchronous updates. Not so good.
Since I can't use async updates in my case I just made that
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let mode = RunLoop.current.currentMode, mode == .tracking, scrollView.contentOffset.y == 0 else {
previousOffset = scrollView.contentOffset
return
}
scrollView.setContentOffset(previousOffset, animated: false)
}
Don't think its brilliant solution but I have no idea how to fix it another way.