1

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

Chaudhry Talha
  • 4,570
  • 7
  • 30
  • 71
  • 1
    You can use this library for tag view: https://github.com/ElaWorkshop/TagListView – Kishan Bhatiya Jan 09 '20 at 09:50
  • Add your output image. – dahiya_boy Jan 09 '20 at 09:53
  • @dahiya_boy added the output image. – Chaudhry Talha Jan 09 '20 at 09:56
  • 1
    @ChaudhryTalha You need to use [this method](https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrect) to get the exact width of the string. Add some margin after that so that your UI looks good. I had done same in Obj-c , [link](https://github.com/thedahiyaboy/TDTagIndex/blob/master/TDTagListCollection/TDTagListCollection/ViewController.m), as its one line code so you can convert it ito swift too. – dahiya_boy Jan 09 '20 at 10:09
  • @dahiya_boy I've added `let tagSize = (tagsArray[indexPath.row] as NSString).boundingRect(with: (tagsArray[indexPath.row] as NSString).size(withAttributes: nil), options: .usesLineFragmentOrigin, attributes: nil, context: nil).size` by following the objective c link and then `return CGSize(width: tagSize.width, height: 40)` in the `sizeForItemAt` function but it still didn't work. – Chaudhry Talha Jan 09 '20 at 10:24
  • This may [help](https://stackoverflow.com/questions/25895311/uicollectionview-self-sizing-cells-with-auto-layout). – Manav Jan 09 '20 at 10:24

1 Answers1

1

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

Roman Podymov
  • 3,416
  • 3
  • 28
  • 49