Qwe Qwe
Qwe Qwe

Reputation: 493

Swift scrollToItem works weird

It worked fine at first with swiping as in the video. But When I click the next button to go to the next page, the cell moves up.

Video

UICollectionViewController class:

private var pageControl: UIPageControl = {
    let pc = UIPageControl()
    pc.currentPage = 0
    pc.numberOfPages = 3
    pc.currentPageIndicatorTintColor = .black
    pc.pageIndicatorTintColor = UIColor.rgb(red: 172, green: 172, blue: 172)
    return pc
}()


override func viewDidLoad() {
    super.viewDidLoad()
    
    self.title = "Test"
    
    collectionView.backgroundColor = .white
    collectionView.register(UserQuickGuideCell.self, forCellWithReuseIdentifier: "cellId")
    collectionView.isPagingEnabled = true
    
    setupPageControl()
}

private func setupPageControl() {
    self.view.addSubview(pageControl)
    self.pageControl.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        self.pageControl.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
        self.pageControl.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        self.pageControl.heightAnchor.constraint(equalToConstant: 50)
    ])
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}


override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! UserQuickGuideCell
    cell.listener = self
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width, height: view.safeAreaLayoutGuide.layoutFrame.size.height )
}

override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    let x = targetContentOffset.pointee.x
    pageControl.currentPage = Int(x / view.frame.width)
}

func nextButtonOnClicked() {
    if ( pageControl.currentPage == 2 ) {
        
    } else {

        let nextIndex = pageControl.currentPage + 1
        let indexPath = IndexPath(item: nextIndex, section: 0)
        pageControl.currentPage = nextIndex
        collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
    }
}

Upvotes: 0

Views: 231

Answers (2)

Mehrdad
Mehrdad

Reputation: 1208

When you are using CompositionalLayout do not set both

collectionView.isPagingEnabled = true

in setup of your collection and

let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .paging

in UICollectionViewCompositionalLayout setup.

Only set the second one in UICollectionViewCompositionalLayout.

Upvotes: 0

Raja Kishan
Raja Kishan

Reputation: 19044

First return the size of the collection view frame, not needed to pass the view frame. It will help you when the collection views frame changes.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return collectionView.frame.size
}

also, scrollToItem with .isPagingEnabled is broken in iOS 14. You can use this workaround.

collectionView?.isPagingEnabled = false
collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
collectionView?.isPagingEnabled = true

Upvotes: 1

Related Questions