Search code examples
iosswiftuicollectionviewuicollectionviewlayout

UICollectionView horizontal scrolling


I am having a UICollectionView with a horizontal scroll. Here is my collectionView:

fileprivate(set) lazy var collectionView: UICollectionView = {
        let width = UIScreen.main.bounds.width.multiplied(by: 0.9)
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: width, height: 50)

        layout.sectionInset = UIEdgeInsets(top: 20, left: 20, bottom: 10, right: 20)
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 20

        let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: 50), collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .red
        collectionView.isPagingEnabled = true
        return collectionView
    }() 

and it looks like that:

enter image description here

As you see I have collectionView.isPagingEnabled = true in the code since I want the paging effect. So what I am trying to achieve is to make the items look like in the picture above (20 spacing on left and right) in every other page, but so far I am getting :

enter image description here

Any ideas/tips how to get to the desired behaviour ?


Solution

  • Here's the UICollectionViewDelegateFlowLayout I used in my test project to achieve what you want.

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.width.multiplied(by: 0.9), height: 50.0)
    }
    
    // item spacing = vertical spacing in horizontal flow
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return (UIScreen.main.bounds.width.multiplied(by: 0.1))
    }
    
    // line spacing = horizontal spacing in horizontal flow
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return (UIScreen.main.bounds.width.multiplied(by: 0.1))
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: (UIScreen.main.bounds.width.multiplied(by: 0.1) / 2.0), bottom: 0, right: (UIScreen.main.bounds.width.multiplied(by: 0.1) / 2.0))
    }
    

    With your code it'd be like that:

    fileprivate(set) lazy var collectionView: UICollectionView = {
        let width = UIScreen.main.bounds.width.multiplied(by: 0.9)
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: width, height: 50)
    
        layout.sectionInset = UIEdgeInsets(top: 20, left: UIScreen.main.bounds.width.multiplied(by: 0.1) / 2.0, bottom: 10, right: UIScreen.main.bounds.width.multiplied(by: 0.1) / 2.0)
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = UIScreen.main.bounds.width.multiplied(by: 0.1)
        layout.minimumInteritemSpacing = UIScreen.main.bounds.width.multiplied(by: 0.1) // or any value you want
    
        let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: 50), collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .red
        collectionView.isPagingEnabled = true
        return collectionView
    }()