1 year ago

#68040

test-img

JohnLiu

UICollectionView scrollToItem() wrong position on the first time

I am trying to create a carousel view with collection view and page control. Whenever I tapped the page control, I will call the collectionView.scrollToItem(). But when I launch my app, the first time I tap on the page control. It is always out of position. Then the tap afterward will be at the right position.

Initial: Initial Image

First Scroll To Item: First Scroll To Item

Afterward: Afterward

Here is my code, I hardcoded the selectedPage to be 1 all the time. But Still the first time is out of position.

class ViewController: UIViewController{

   @IBOutlet weak var carouselView: UICollectionView!
   @IBOutlet weak var dots: UIPageControl!

   override func viewDidLoad() {
       super.viewDidLoad()
       setupCarouselView()
   }

   override func viewWillLayoutSubviews() {
       setupCarouselView()
   }

   func setupCarouselView() {
       carouselView.delegate = self
       carouselView.dataSource = self
    
       let layout = UICollectionViewFlowLayout()
       layout.scrollDirection = .horizontal
       layout.minimumInteritemSpacing = 0
       layout.minimumLineSpacing = 0
    
       carouselView.isPagingEnabled = true
       carouselView.collectionViewLayout = layout
       carouselView.showsHorizontalScrollIndicator = false
       carouselView.contentInsetAdjustmentBehavior = .never
    
       dots.numberOfPages = 5
       dots.currentPage = 0
   }

   @IBAction func pageControlTapped(_ sender: UIPageControl) {
       //let selectedPage = sender.currentPage
       let selectedPage = 1
       print("selectedPage: \(selectedPage)")
       let indexPath = IndexPath(item: selectedPage, section: 0)
       carouselView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
    
       DispatchQueue.main.async {
           self.carouselView.updateConstraints()
       }
   }
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

   func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
       let width = UIScreen.main.bounds.width
       return CGSize(width: width, height: 200)
   }

   func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
       dots.numberOfPages = 5
       return 5
   }

   func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
       let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CarouselCollectionViewCell
       cell.label.text = "\(indexPath.item)"
    
       return cell
   }

   func scrollViewDidScroll(_ scrollView: UIScrollView) {
       dots.currentPage = Int(
        (carouselView.contentOffset.x / carouselView.frame.width)
            .rounded(.toNearestOrAwayFromZero)
       )
   }

   func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
   {
       dots.currentPage = Int(floorf(Float(scrollView.contentOffset.x / scrollView.frame.width)))
   }
 }

ios

swift

carousel

collectionview

uipagecontrol

0 Answers

Your Answer

Accepted video resources