Multiple cells for a single UICollectionView

这一生的挚爱 提交于 2020-01-02 08:15:11

问题


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)

回答1:


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.




回答2:


I just want to mention this, for any future users who might wonder how to do that. Now, I think it's much easier to just use the indexPath.item and check whether or not it's cell 1 or cell 2. Here's an example

if indexPath.item == 0 
{
   // Cell 1
   let cell1 = let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell1", for: indexPath) as! Cell1
   return cell1
}
else
{
   // Cell 2
   let cell2 = let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell2", for: indexPath) as! Cell1
   return cell2
}

In case you have more than 2 custom UICollectionViewCells then just add else if statements and check against its indexPath.item.




回答3:


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)
    }

}


来源:https://stackoverflow.com/questions/43273027/multiple-cells-for-a-single-uicollectionview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!