Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set initial scroll position of the collection view

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
        }
    }
}
like image 570
danilabagroff Avatar asked Dec 19 '22 08:12

danilabagroff


2 Answers

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

like image 123
Alexandr Vysotsky Avatar answered Dec 20 '22 22:12

Alexandr Vysotsky


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.

like image 21
LiLi Kazine Avatar answered Dec 20 '22 21:12

LiLi Kazine