3

I want to be able to call my UICollectionViewCell class in the sizeForItemAtIndexPath function. Like this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let cell = MyCollectionViewCell()

    let itemHeights = cell.titleLabel.frame.size.height + cell.subtitleLabel.frame.size.height + 20 

    return CGSize(width: self.view.frame.size.width - 30, height: itemHeights + cell.thumbnail.frame.size.height)

}

The problem is that cell.titleLabel.frame.size.height, cell.subtitleLabel.frame.size.height, and cell.thumbnail.frame.size.height are all returning nil. I assume this is because whenever sizeForItemAtIndexPath is called, the cell has not loaded yet and cellForItemAtIndexPath has not been called, yet.

I need to know this because the cell.titleLabel can be multiple lines and widths which are set in the cellForItemAtIndexPath.

Any idea?

Jacob Cavin
  • 1,735
  • 3
  • 11
  • 34
  • Maybe this can help https://stackoverflow.com/questions/30405063/setting-cell-height-of-collectionview-doesnt-really-expand-cell-for-scrolling – ryantxr Aug 24 '17 at 12:28
  • 2
    You shouldn't dequeue a cell in a function other than `cellForItemAt:` Even if you do dequeue a cell, you won't get a cell that is populated with the values for that index path. You will need to calculate values for the height based on the data for the cell, or use an automatic cell height and provide a reasonable `estimatedSize` for your cell – Paulw11 Aug 24 '17 at 12:29

1 Answers1

0

sizeForItemAt is called before your cell is actually created and configured with the required data. That is the reason you don't get correct data that you need.

Try this:

Create a dummy cell in sizeForItemAt by dequeuing it from the collectionView. Configure the cell with actual data that you want to display. After configuring it get what data you need, i.e.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
    //Configure your cell with actual data
    cell.contentView.layoutIfNeeded()
    //Calculate the size and return
}
PGDev
  • 20,976
  • 5
  • 29
  • 68
  • Caution: dequeueReusableCell was working dependably for me in sizeForItemAt through dozens of simulator runs, both iPhone and iPad, and many iPhone device runs, and then crashed the app when run on an iPad Air. I'm having better results now with the sizingCell approach described here: https://stackoverflow.com/a/53786943/1473527 – Matt Bearson Sep 12 '19 at 22:37