UICollectionView Self Sizing Cells

Viewed 3733

So I'm trying to figure out how to self size collection view cells. So I have a ViewController and I dragged a collectionView inside the ViewController. I am not using a xib file, I am using a prototype cell. Now I can't seem to figure out how to self size the cell. It's not as easy as the table view. I've tried the following that I found.

if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {

        layout.estimatedItemSize = CGSize(width: view.frame.width, height: 100)
        layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
    }

Then I found another one that creates a dummyCell, that looks something like this. This crashes my app though.

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

    let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50)
    let dummyCell = CommentCell(frame: frame)
    let comment = comments[indexPath.item]
    print(comment.text)

    dummyCell.comment = comment
    dummyCell.layoutIfNeeded()

    let targetSize = CGSize(width: view.frame.width, height: 1000)
    let estimateSize = dummyCell.systemLayoutSizeFitting(targetSize)
    let height = max(45 + 8 + 8, estimateSize.height)
    return CGSize(width: view.frame.width, height: height)

}

So would I need a collection view controller instead of a view controller. How would I be able to self size cells without using a collectionViewController or a nib file? Thanks

1 Answers

Assuming you have constraints in the cell NIB/prototype, you want to set itemSize to .automaticSize:

if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    layout.estimatedItemSize = CGSize(width: view.frame.width, height: 100)
    layout.itemSize = UICollectionViewFlowLayout.automaticSize
}

You haven’t shared where you are setting this, but if done in viewDidLoad, the view.frame.width might not be what you think it is. You will want to double check that...

Related