Home > Software design >  How to set CollectionView itemHeight to the same as highest item?
How to set CollectionView itemHeight to the same as highest item?

Time:08-24

I have a task like this: Set all cell's height as same as the highest item, and I don't know the size of each cell in advance. For example:

// I don't know the size of each cell in advance

cellOne's.bounds.height = 60
cellTwo's.bounds.height = 70
cellThree's.bounds.height = 80

**Then collectionView's itemHeight should be 80**

Here is my collectionView:

// the cell only have a label which get text from net requesting
private lazy var collectionView: UICollectionView = {
        let collectionView = UICollectionView.init(frame: .zero, collectionViewLayout: flowLayout)
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.showsVerticalScrollIndicator = false
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.scrollsToTop = false
        collectionView.decelerationRate = .fast
        collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        return collectionView
    }()

And this is what I have tried, I use a variable "maxHeight" to present current max height:



// use this to set maxHeight
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyNameCell

    cell.configData(model[indexPath.row])

    maxHeight = max(maxHeight, cell.bounds.height)
    
    cell.backgroundColor = .clear    
    return cell
}

// use this to set cell's height, right?
extension MyNameController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        return CGSize(width: 40, height: maxHeight)
    }
}

It didn't work, is that because the net request is async? I always get the same height(like 60, not 80....

CodePudding user response:

Are you trying to have a predefined set height for all cells? Or a dynamic size according to their content?

The cell height in func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell is not defined yet!

You can see that func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize will be called after for the same IndexPath

If you know the size for each cell (i.e IndexPath) in advance you just need to check what is the current IndexPath when func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize is called and set the size, something like this: Lets say we know the height in advance and incorporate it into our model

struct CellModel {
  let title: String
  let size: CGSize
}
var cellsModels: [CellModel]
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  return self.cellModels[indexPath.row].size
}

If the size is not known in advance, you will have to build a custom UICollectionViewLayout

There are numerous projects that can help you dig into the API and configure the layout dynamically Link1 Link2 Link3

CodePudding user response:

actually, if you just want all cell has the highest height, my code should be work.

  • Related