On a collectionView with Paging enabled, scrollToItem does not work

I have a collectionView with Paging enabled. I also added buttons with scrollToItem functionality in their action, so that the user can click and go to the next or previous cell of the collectionView.
Everything worked fine until ios 14. Now if I disable Paging on the collectionView, scrollToItem works fine, but with Paging enabled, if I click next or previous (scrollToItem), nothing happens. Now with Paging disabled if I try to swipe the screen in order to scroll to another cell, the collection view does not stop on the cell- just floats freely (obviously caused by disabling Paging).

Anyone has idea why is this?
I have the same issue on iOS 14. On iOS 13.x all works fine. As workaround I have to set contentOffset manually instead of using "scrollToItem"


I'm using UICollectionViewFlowLayout to override the targetContentOffset and its work
Code Block
class HomeCVColumnFlowLayout: UICollectionViewFlowLayout {
    var cellsPerRow: Int
    let type : String?
    override var itemSize: CGSize {
        get {
            guard let collectionView = collectionView else { return super.itemSize }
            let marginsAndInsets = sectionInset.left + sectionInset.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
            let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
            let itemHeight = collectionView.bounds.size.height - sectionInset.top - sectionInset.bottom
            return CGSize(width: itemWidth, height: itemHeight)
        }
        set {
            super.itemSize = newValue
        }
    }
    init(cellsPerRow: Int, minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero, type: String = "") {
        self.cellsPerRow = cellsPerRow
        self.type = type
        super.init()
        self.scrollDirection = UICollectionView.ScrollDirection.horizontal
        self.minimumInteritemSpacing = minimumInteritemSpacing
        self.minimumLineSpacing = minimumLineSpacing
        self.sectionInset = sectionInset
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext {
        let context = super.invalidationContext(forBoundsChange: newBounds) as! UICollectionViewFlowLayoutInvalidationContext
        context.invalidateFlowLayoutDelegateMetrics = newBounds != collectionView?.bounds
        return context
    }
    override func targetContentOffset(
        forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        guard let collectionView = collectionView else { return proposedContentOffset }
        let pageWidth = itemSize.width + minimumLineSpacing
        let currentPage: CGFloat = collectionView.contentOffset.x / pageWidth
        let nearestPage: CGFloat = round(currentPage)
        let isNearPreviousPage = nearestPage < currentPage
        var pageDiff: CGFloat = 0
        let velocityThreshold: CGFloat = 0.5
        if isNearPreviousPage {
          if velocity.x > velocityThreshold {
            pageDiff = 1
          }
        } else {
          if velocity.x < -velocityThreshold {
            pageDiff = -1
          }
        }
        let x = (nearestPage + pageDiff) * pageWidth
        let cappedX = max(0, x)
        return CGPoint(x: cappedX, y: proposedContentOffset.y)
      }
}


You can use UICollectionViewDelegateFlowLayout
     // Compute the dimension of a cell for an NxN layout with space S between
    // cells. Take the collection view's width, subtract (N-1)*S points for
    // the spaces between the cells, and then divide by N to find the final
    // dimension for the cell's width and height.

Code Block
   func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtindexPath: IndexPath) -> CGSize {
     let cellsAcross: CGFloat = 1
     let spaceBetweenCells: CGFloat = 1
    let dim = (self.cvImageViewer.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
     return CGSize(width: dim, height: self.cvImageViewer.bounds.height)
  }

This solved the issue for me

Same issue here.
i also check in my side i faced same issue in new Xcode 12 or 12.1. in older Xcode 11.5 all working properly. Because of this one issue i can't move to latest Xcode with my big project. I request to apple Xcode developer community please solve this small thing as soon as possible. There are so many developer like us can't move no next latest Xcode and technologies due to this Xcode issue. please solve a collectionView with Paging enabled, scrollToItem methods.

Thanks

Hi guys!

I've encountered this issue on iOS 14.x and XCode 12.x.
The solution that worked for me was to use collectionView.scrollRectToVisible(rect, animated: true)

Hope that helps! :)
On a collectionView with Paging enabled, scrollToItem does not work
 
 
Q