Search code examples
iosswiftxcodeuicollectionviewcarousel

How to trigger didSelectItemAtIndexPath at select center cell once the scroll end in ios swift?


Here UPCarouselFlowLayout is used for carousel scroll. As of now, user must tap a cell in order to trigger collection view didSelectItemAtIndexPath. Is there a way to select the center cell once the scrolling ended automatically?

here is the code i used to carousel:

 let layout = UPCarouselFlowLayout()
    layout.itemSize = CGSize(width: 211, height: 75)
    layout.scrollDirection = .horizontal
    layout.spacingMode = UPCarouselFlowLayoutSpacingMode.fixed(spacing: 10)
    layout.spacingMode = UPCarouselFlowLayoutSpacingMode.overlap(visibleOffset: 65)
    carCollection.collectionViewLayout = layout

here the code used for collection view:

     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {


    return carCategory.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! carCollectionViewCell

    cell.carName.text = carCategory[indexPath.row]
    cell.carImage.image = UIImage(named: carCategoryImage[indexPath.row])
    cell.carMeters.text = carCategoryMeter[indexPath.row]

    return cell

}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        print("selected index::\(indexPath.row)")

}

Solution

  • If you look at ViewController.swift from the Demo included with ** UPCarouselFlowLayout**, you will see the function scrollViewDidEndDecelerating. That is triggered when the scroll stops moving and a cell become the "center" cell.

    In that function, the variable currentPage is set, and that's where the labels below the collection view are changed.

    So, that's one place to try what you want to do.

    Add the two lines as shown here... when the scroll stops, you create an IndexPath and manually call didSelectItemAt:

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let layout = self.collectionView.collectionViewLayout as! UPCarouselFlowLayout
        let pageSide = (layout.scrollDirection == .horizontal) ? self.pageSize.width : self.pageSize.height
        let offset = (layout.scrollDirection == .horizontal) ? scrollView.contentOffset.x : scrollView.contentOffset.y
        currentPage = Int(floor((offset - pageSide / 2) / pageSide) + 1)
    
        // add these two lines      
        let indexPath = IndexPath(item: currentPage, section: 0)
        collectionView(self.collectionView, didSelectItemAt: indexPath)
    }
    

    You will almost certainly want to add some error checking and additional functionality (like only calling didSelect if the cell actually changed, as opposed to just sliding it a little but remaining on the current cell), but this is a starting point.