I have a UICollectionView
using a standard UICollectionViewFlowLayout
with an estimatedItemSize
set to UICollectionViewFlowLayoutAutomaticSize
.
Once I call collectionView.reloadData()
the scroll position of the view resets to CGPoint(x: 0, y: 0)
. I know that .reloadData()
should only be used as a last resort, it is necessary in my scenario though. I have found out so far that it is probably caused by not returning an item size through collectionView(_:layout:sizeForItemAt:)
. (Any solutions for that analogous to UITableView
’s tableView:estimatedHeightForRowAtIndexPath:
like in this StackOverflow answer would be highly appreciated).
I had the same issue and solved it by subclassing the collection view, override reloadData to temporary store the current contentOffset and then listening to changes to the contentOffset and changing it back if i have anything stored in my temporary offset variable
class MyCollectionView : UICollectionView {
deinit {
removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
}
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
self.addObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset), options: [.old, .new], context: nil)
}
private var temporaryOffsetOverride : CGPoint?
override func reloadData() {
if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout, flowLayout.estimatedItemSize == UICollectionViewFlowLayout.automaticSize {
temporaryOffsetOverride = contentOffset
}
super.reloadData()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(UIScrollView.contentOffset) {
if let offset = temporaryOffsetOverride {
temporaryOffsetOverride = nil
self.setContentOffset(offset, animated: false)
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With