title: Set the size of a collectionView with cell of different width, in a horizontal scrolling
body: <p>I'm trying to set a UICollectionView as a horizontal menu, on top of another UICollectionView (but that's irrelevant). </p>
  
  <p>Now my cells are basically composed of label, which are as you can imagine of different width. So I tried to calculate the size with this function : </p>
  
  <pre><code>func getSizeOfCell(string: String, font: UIFont) -&gt; CGSize {
      let textString = string as NSString
      let textAttributes = [NSFontAttributeName: font]
      let size = textString.boundingRect(with: CGSize(width: 320, height: 2000), options: .usesLineFragmentOrigin, attributes: textAttributes, context: nil)
      return CGSize(width: size.width, height: size.height)
  }
  </code></pre>
  
  <p>Which is not really doing a good job, as you can see : 
  <a href="https://i.stack.imgur.com/qlswb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/qlswb.png" alt="enter image description here"></a></p>
  
  <p>The view containing the label are too big when the string is long. </p>
  
  <p>I'm kind of forced to give sizeForItemAt a CGSize right ? I can't just ask my CollectionView to get automatically the size of a cell based on a label it contains ? </p>
  
  <p>[edit] so here's my cell class :</p>
  
  <pre><code>class MenuCell: UICollectionViewCell {
  override init(frame: CGRect) {
      super.init(frame: frame)
  
      setupViews()
  }
  
  override var isSelected: Bool {
      didSet {
          labelTitre.textColor = isSelected ? UIColor.black : .lightGray
      }
  }
  
  let labelTitre : UILabel = {
      let label = UILabel()
      label.textColor = .gray
      return label
  }()
  
  func setupViews() {
      backgroundColor = UIColor.white
      addSubview(labelTitre)
      addConstraintsWithFormat(format: "H:[v0]", views: labelTitre)
      addConstraintsWithFormat(format: "V:[v0]", views: labelTitre)
      addConstraint(NSLayoutConstraint(item: labelTitre, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
      addConstraint(NSLayoutConstraint(item: labelTitre, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
  
  }
  
  
  
  required init?(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
  }
  }
  </code></pre>
  
  <p>And here's how I construct my collectionView :</p>
  
  <pre><code>lazy var customCollectionView : UICollectionView = {
      let layout = UICollectionViewFlowLayout()
      layout.scrollDirection = .horizontal
      layout.minimumLineSpacing = 0
      layout.minimumInteritemSpacing = 0
      layout.estimatedItemSize = CGSize(width: 60, height: 30)
      let cv  = UICollectionView(frame: .zero, collectionViewLayout: layout)
      cv.collectionViewLayout = layout
      cv.backgroundColor = UIColor.white
      cv.dataSource = self
      cv.delegate = self
      return cv
  
  }()
  </code></pre>
  
  <p>with also in the viewDidLoad() of my viewController: </p>
  
  <pre><code>    customCollectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)
      addSubview(customCollectionView)
      addConstraintsWithFormat(format: "V:|[v0]|", views: customCollectionView)
      addConstraintsWithFormat(format: "H:|[v0]|", views: customCollectionView)
  </code></pre>