1

I have a UICollectionView that has horizontal scrolling. I need to place all my collection view cells in two rows and both should scroll horizontally. The layout is as shown in the screenshot.

How it is supposed to be

As shown in the above screenshot, I am going to have to build two rows which will scroll horizontally, i.e., both rows will scroll together in the same direction.

I had earlier considered using sections in the scroll view, but then the scrolling would probably be independent, and so, I am hoping to find a better solution.

I looked into this link here : A similar post

This link uses a tableview to hold multiple collection views. Even though solution seems good, I am really not sure if it could work for me, I wish to know if there is a better alternative. 
 I looked into other stack overflow posts regarding the same (Can’t remember which though), but they did not help much. 


Now normally, we would have two columns in the collection view and we can scroll vertically. Instead of this behavior, is there any way to have two rows in a UICollectionView which can scroll horizontally and simultaneously?

Should I consider using two collection views and have some logic that binds the scrolling of both the views? (I’d rather not have two UICollectionviews just to solve this problem)

Also, I am doing this through pure code. No storyboards or xib files have been used.

Cerlin
  • 6,622
  • 1
  • 20
  • 28
Pavan Vasan
  • 391
  • 1
  • 9
  • 28
  • 1
    If you can group cells vertically, create one cell with two row views so that it looks like two cells. Also disable UICollectionViewCell selection and add gesture handlers – Cerlin Apr 08 '19 at 06:49
  • 1
    I don't follow. Do you mean to say that I should have two UIViews similar to the cells inside a UICollectionViewCell, one below the other? – Pavan Vasan Apr 08 '19 at 06:56
  • Yes, if you can group views vertically – Cerlin Apr 08 '19 at 06:58
  • Hmmm, seems like a hack to me. But something is better than nothing. @CerlinBoss: Thanks for the suggestion. Would be great if a better solution is there, but nevertheless, this will work out for me for the time being. – Pavan Vasan Apr 08 '19 at 07:04

2 Answers2

4

Can you try the code below?

I was able to do this i guess

class CollectionViewController: UIViewController {
    @IBOutlet weak var collectionView: UICollectionView!

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

    fileprivate func setUpCollectionView() {

        let collectionFlowLayout = UICollectionViewFlowLayout()

        collectionFlowLayout.scrollDirection = .horizontal
        collectionFlowLayout.itemSize = CGSize(width: 145, height: 145)
        collectionView.setCollectionViewLayout(collectionFlowLayout, animated: true)
        collectionView.delegate = self
        collectionView.dataSource = self
    }
}

extension CollectionViewController: UICollectionViewDelegate, UICollectionViewDataSource {

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

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

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCollectionViewCell", for: indexPath)

        if indexPath.row % 2 == 0 {
            cell.contentView.backgroundColor = UIColor.red
        } else {
            cell.contentView.backgroundColor = UIColor.green
        }

        return cell
    }
}

NOTE: I have set collectionView height as 300

OUTPUT

enter image description here

Cerlin
  • 6,622
  • 1
  • 20
  • 28
0

Use 2 collectionView

    let CellId1 = "CellId1"
    lazy var collectionViewOne: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 0
        let width = collectionView.frame.width
        let collectionViewOne = UICollectionView(frame: CGRect(x: 0, y: 100, width: width, height: 100), collectionViewLayout: layout)
        collectionViewOne.showsHorizontalScrollIndicator = false
        collectionViewOne.backgroundColor = .red
        return collectionViewOne
    }()

    let CellId2 = "CellId2"
    lazy var collectionViewTwo: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 0
        let collectionViewTwo = UICollectionView(frame: CGRect(x: 0, y: 250, width: width, height: 100), collectionViewLayout: layout)
        collectionViewTwo.backgroundColor = .blue
        return collectionViewTwo
    }()

then for obtaining the numberOfItem and cellForRow:

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

        if collectionView == self.collectionViewOne {
            return 10
        } else if collectionView == self.collectionViewTwo {
            return 20
        } 

    }

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

        if collectionView == self.collectionViewOne {
            let Cell1 = collectionViewOne.dequeueReusableCell(withReuseIdentifier: CellId1, for: indexPath)
Cell1.backgroundColor = .green

            return Cell1

        } else if collectionView == self.collectionViewTwo {
            let Cell2 = collectionViewTwo.dequeueReusableCell(withReuseIdentifier: CellId2, for: indexPath )
Cell2.backgroundColor = .purple
            return Cell2
        } 

    }

and don't forget to register the collectionView in viewDidLoad()


    collectionViewOne.delegate = self
        collectionViewOne.dataSource = self

        collectionViewTwo.delegate = self
        collectionViewTwo.dataSource = self

collectionViewOne.register(Cell1.self, forCellWithReuseIdentifier: storyCell)
        collectionViewTwo.register(Cell2.self, forCellWithReuseIdentifier: cardCell)
Picker
  • 688
  • 1
  • 7
  • 7