I have tried many solutions but none of them work. The question is simple — how to scroll down during viewDidLoad
, viewWillAppear
or viewDidAppear
without visual(jump) effect?
What I have now:
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if (!self.layoutFlag) {
if let lastCell: IndexPath = self.lastCellIndexPath {
self.collectionView?.scrollToItem(at: lastCell, at: UICollectionViewScrollPosition.bottom, animated: true)
self.layoutFlag = true
}
}
}
I found only one way to set initial scroll position:
call my scroll function in viewDidLayoutSubviews
var isScrolled = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !isScrolled && levelCollectionView.visibleCells.count > 0 {
isScrolled = true
// scroll
}
}
it doesn't look as correct answer but it works
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
}
}
Just wrap scrollToItem
within an async block. It works perfectly, no visual transition and easy to apply.
How it worked I can only guess. Synchronously scroll the collection view in viewDidLoad will not do because it hasn't been laid out yet. Commit scroll in an async block adds this action to the next runloop task, when next runloop executes, which is exactly when ui will be drawn, the scroll executes right after, and displayed in the same frame.
All a above is just a guess, anyone has any idea I'd be glad to learn.
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