Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple cells for a single UICollectionView

In my collection view, the cell class must have completely different appearance for different kinds of data in the array.

I am looking for a way to create multiple cells and choose a different one according to the input data, so for example :

internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell1 = collectionView.dequeueReusableCell..  as! kind1
    let cell2 = collectionView.dequeueReusableCell.. as! kind2
   // here choose a different one for each kind of data
    return cell1
}

I am trying to understand if :

  1. How to do this and if its the right way in terms of memory ?
  2. Is it a good design? how would you go about making a completely different layout of a single cell? ( creating views and hiding them seems like a bad approach)
like image 211
Curnelious Avatar asked Dec 19 '22 08:12

Curnelious


2 Answers

You need to do something like this

First register multiple cell -

[collectionView registerNib:[UINib nibWithNibName:@"CollectionViewCellKind1" bundle:nil] forCellWithReuseIdentifier:@"CollectionViewCellKind1"]
[collectionView registerNib:[UINib nibWithNibName:@"CollectionViewCellKind2" bundle:nil] forCellWithReuseIdentifier:@"CollectionViewCellKind2"]

Now implement cellForItemAt like show -

internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if (data.kind == kind1) {
        let cell1 = collectionView.dequeueReusableCell..  as! kind1

        return cell1
    } else {
        let cell2 = collectionView.dequeueReusableCell.. as! kind2

        return cell2
    }
}

by checking the type of the data you can determine the cell.

like image 71
J. Koush Avatar answered Jan 10 '23 01:01

J. Koush


Swift 5 example, change depending on your needs.

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(collectionView)

        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
        collectionView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
        collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true

        registerCells()
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 0
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .white
        cv.dataSource = self
        cv.delegate = self
        cv.isPagingEnabled = true
        return cv
    }()

    var cellId = "Cell"
    var celltwoCellId = "CellTwoCell"

    fileprivate func registerCells() {
        collectionView.register(CellOneCell.self, forCellWithReuseIdentifier: cellId)
        collectionView.register(CellTwoCell.self, forCellWithReuseIdentifier: celltwoCellId)
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.item == 0
        {
            // Cell 1
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CellOne
            return cell
        }
        else
        {
            // Cell 2
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: celltwoCellId, for: indexPath) as! CellTwo
            return cell
        }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }

}
like image 44
zkquin Avatar answered Jan 10 '23 01:01

zkquin