Search code examples
iosswiftuicollectionviewuilabeluicollectionviewcell

How to dynamically size CollectionViewCell as per UILabel


I'm creating a suggestion/tags view. Which is basically a horizontal uicollectionview. I've a custom cell in which I just have one label with no autoresizing or auto constraints. And I've an array var tagsArray = ["Label", "A Long Label", "A very long label"] which I am using in the collectionView delegate methods as:

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

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let size = (tagsArray[indexPath.row] as NSString).size(withAttributes: nil)
    return size
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TagCell", for: indexPath) as! TagCollectionViewCell
    cell.tagLabel.text = tagsArray[indexPath.row]
    return cell

}

The second function collectionViewLayout is something that I've picked form stack overflow but when I run it there is no effect on the UILabel.

Here is the output: enter image description here


Solution

  • You don't need to calculate the size of the strings that you want to display. Do the following:

    1. Set collectionView's height equal to the expected height of tags.
    2. Set tagLabel's leading, trailing, top and bottom constraints equal to the corresponding cell's contentView constraints.
    3. Remove your implementation of func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize. The cell size will be calculated automatically if you don't use a custom value for estimatedItemSize. If you want to be sure, add (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.estimatedItemSize = UICollectionViewFlowLayout.automaticSize to the function where you setup all views.

    You will see the following result:

    Running on iPhone 11 Pro Max simulator