title: iOS: Collection view custom tag layout dynamic Height Swift
body: <p>I am trying to create tag list view. Unfortunately I don't know How to work with Custom flow layout. But I found to create pretty tag list. But encountered a problem with multi-line label. If we used the text more than the collection view width, then the <code>attribute.frame.height</code> should be multiplied like <code>40*numberOfLines</code>. Please help to solve this problem.</p>
  <p><strong>Custom Flow Layout:</strong></p>
  <pre><code>import UIKit
  
  class CollectionViewRow {
      var attributes = [UICollectionViewLayoutAttributes]()
      var spacing: CGFloat = 0
  
  
  
      init(spacing: CGFloat) {
          self.spacing = spacing
      }
  
      func add(attribute: UICollectionViewLayoutAttributes) {
          attributes.append(attribute)
      }
  
      var rowWidth: CGFloat {
          return attributes.reduce(0, { result, attribute -&gt; CGFloat in
              return result + attribute.frame.width
          }) + CGFloat(attributes.count - 1) * spacing
      }
  
      func layout(collectionViewWidth: CGFloat) {
           
          var offset = spacing
          
          for attribute in attributes {
              attribute.frame.origin.x = offset
              offset += attribute.frame.width + spacing
          }
      }
  }
  
  class UICollectionViewCenterLayout: UICollectionViewFlowLayout {
      override func layoutAttributesForElements(in rect: CGRect) -&gt; [UICollectionViewLayoutAttributes]? {
          guard let attributes = super.layoutAttributesForElements(in: rect) else {
              return nil
          }
  
          var rows = [CollectionViewRow]()
          var currentRowY: CGFloat = -1
  
          for attribute in attributes {
              if currentRowY != attribute.frame.midY {
                  currentRowY = attribute.frame.midY
                  rows.append(CollectionViewRow(spacing: 10))
              }
              rows.last?.add(attribute: attribute)
          }
  
          rows.forEach { $0.layout(collectionViewWidth: collectionView?.frame.width ?? 0) }
          return rows.flatMap { $0.attributes }
      }
  }
  </code></pre>
  <p><strong>Usage:</strong></p>
  <pre><code>let layout = UICollectionViewCenterLayout()
  layout.estimatedItemSize = CGSize(width: 140, height: 40)
  collectionView.collectionViewLayout = layout
  
  collectionView.reloadData()
  </code></pre>
  <p><strong>I tried to change height but It not working expected:</strong></p>
  <pre><code>func layout(collectionViewWidth: CGFloat) {
       
      var offset = spacing
      
      for attribute in attributes {
          attribute.frame.origin.x = offset
          
          let attributeTotalWidth  = attribute.frame.width + spacing
          
          if attributeTotalWidth &gt; collectionViewWidth{
              
              let multiplier: CGFloat  = attributeTotalWidth/collectionViewWidth
              
              let intVal = CGFloat(Int(multiplier))
              let fullNumber = multiplier-intVal &gt; 0 ? intVal+1 : 
              attribute.frame.size.height = fullNumber * 40
          }
          
          offset += attributeTotalWidth
      }
  }
  </code></pre>
  <p>Can you please help me to find out the solution to make variable item height based on the label text content? Thanking you in advance!</p>