1

I have a collection view that scrolls horizontally, but I cannot figure out how to make the cells center and stop at the center of each scroll. So for example if you swift left the next cell should be centered in the middle of the screen, how can I do this? I'll post the collection view I have created:

class TakesViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    

    private lazy var selectionFeedbackGenerator = UISelectionFeedbackGenerator()
    private let cellId = "TakeCell"
    var currentActiveIndex: Int = 0
    
    
    func setUpCollectionView(){
        self.collectionView.isPrefetchingEnabled = true
        self.collectionView.translatesAutoresizingMaskIntoConstraints = false
        self.collectionView.backgroundColor = .clear
        self.collectionView.showsHorizontalScrollIndicator = false
        self.collectionView.showsVerticalScrollIndicator = false
        self.collectionView.contentInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
        self.collectionView.alwaysBounceVertical = false
        self.collectionView.alwaysBounceHorizontal = false
        self.collectionView.decelerationRate = .fast
        self.collectionView.configureForPeekingDelegate()
        self.collectionView.register(UINib(nibName: "TakesCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "TakeCell")
    }
    
    init() {
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumLineSpacing = 15
        super.init(collectionViewLayout: flowLayout)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.delegate = self
        collectionView.dataSource = self
        setUpCollectionView()

    }
    
    
    

}

extension TakesViewController {
    
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 12
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellId, for: indexPath) as? TakeCollectionViewCell else {return UICollectionViewCell()}
    
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 320, height: 575)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

        //Where elements_count is the count of all your items in that
        //Collection view...
        let cellCount = CGFloat(12)

        //If the cell count is zero, there is no point in calculating anything.
        if cellCount > 0 {
            let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
            let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing

            //20.00 was just extra spacing I wanted to add to my cell.
            let totalCellWidth = cellWidth*cellCount + 20.00 * (cellCount-1)
            let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right

            if (totalCellWidth < contentWidth) {
                //If the number of cells that exists take up less room than the
                //collection view width... then there is an actual point to centering them.

                //Calculate the right amount of padding to center the cells.
                let padding = (contentWidth - totalCellWidth) / 2.0
                return UIEdgeInsets(top: 0, left: padding, bottom: 0, right: padding)
            } else {
                //Pretty much if the number of cells that exist take up
                //more room than the actual collectionView width, there is no
                // point in trying to center them. So we leave the default behavior.
                return UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 40)
            }
        }
        return UIEdgeInsets.zero
    }
}
Noah Iarrobino
  • 1,435
  • 1
  • 10
  • 31
  • You need to enable paging via `isPagingEnabled`, but if your cell isn't as wide as your page you might need an answer from here https://stackoverflow.com/questions/22895465/paging-uicollectionview-by-cells-not-screen – Paulw11 Aug 25 '21 at 01:48
  • Yeah I want the other cells peeking a little bit, I'll check that answer. Thanks – Noah Iarrobino Aug 25 '21 at 02:10

1 Answers1

1

It's a scroll view. Where it stops when the user lets go is up to you.

https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619385-scrollviewwillenddragging

matt
  • 515,959
  • 87
  • 875
  • 1,141