title: Dynamic-height UICollectionView inside a dynamic-height UITableViewCell
body: <p>I have a horizontal <code>UICollectionView</code> pinned to all edges of a <code>UITableViewCell</code>. Items in the collection view are dynamically sized, and I want to make the table view's height equal to that of the tallest collection view cell.</p>
  
  <p>The views are structured as follows: </p>
  
  <blockquote>
    <p>UITableView</p>
    
    <blockquote>
      <p>UITableViewCell</p>
      
      <blockquote>
        <p>UICollectionView</p>
        
        <blockquote>
          <p>UICollectionViewCell</p>
          
          <p>UICollectionViewCell</p>
          
          <p>UICollectionViewCell</p>
        </blockquote>
      </blockquote>
    </blockquote>
  </blockquote>
  
  <pre><code>class TableViewCell: UITableViewCell {
  
      private lazy var collectionView: UICollectionView = {
          let collectionView = UICollectionView(frame: self.frame, collectionViewLayout: layout)
          return collectionView
      }()
  
      var layout: UICollectionViewFlowLayout = {
          let layout = UICollectionViewFlowLayout()
          layout.estimatedItemSize = CGSize(width: 350, height: 20)
          layout.scrollDirection = .horizontal
          return layout
      }()
  
      override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
          super.init(style: style, reuseIdentifier: reuseIdentifier)
  
          let nib = UINib(nibName: String(describing: CollectionViewCell.self), bundle: nil)
          collectionView.register(nib, forCellWithReuseIdentifier: CollectionViewCellModel.identifier)
  
          addSubview(collectionView)
  
          // (using SnapKit)
          collectionView.snp.makeConstraints { (make) in
              make.leading.equalToSuperview()
              make.trailing.equalToSuperview()
              make.top.equalToSuperview()
              make.bottom.equalToSuperview()
          }
      }
  
      override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -&gt; CGSize {
  
          collectionView.layoutIfNeeded()
          collectionView.frame = CGRect(x: 0, y: 0, width: targetSize.width , height: 1)
  
          return layout.collectionViewContentSize
      }
  
      override func layoutSubviews() {
          super.layoutSubviews()
  
          let spacing: CGFloat = 50
          layout.sectionInset = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: spacing)
          layout.minimumLineSpacing = spacing
      }
  }
  
  
  class OptionsCollectionViewCell: UICollectionViewCell {
  
      @IBOutlet weak var imageView: UIImageView!
      @IBOutlet weak var titleLabel: UILabel!
  
      override func awakeFromNib() {
          super.awakeFromNib()
  
          contentView.translatesAutoresizingMaskIntoConstraints = false
  
      }
  
      required init?(coder aDecoder: NSCoder) {
          super.init(coder: aDecoder)
      }
  
      override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -&gt; CGSize {
  
          return contentView.systemLayoutSizeFitting(CGSize(width: targetSize.width, height: 1))
      }
  }
  
  class CollectionViewFlowLayout: UICollectionViewFlowLayout {
  
      private var contentHeight: CGFloat = 500
      private var contentWidth: CGFloat = 200
  
      override func layoutAttributesForElements(in rect: CGRect) -&gt; [UICollectionViewLayoutAttributes]? {
          if let attrs = super.layoutAttributesForElements(in: rect) {
             // perform some logic
             contentHeight = /* something */
             contentWidth = /* something */
             return attrs
          }
          return nil
      }
  
      override var collectionViewContentSize: CGSize {
          return CGSize(width: contentWidth, height: contentHeight)
      }
  }
  </code></pre>
  
  <p>In my <code>UIViewController</code>, I have <code>tableView.estimatedRowHeight = 500</code> and <code>tableView.rowHeight = UITableView.automaticDimension</code>.</p>
  
  <p>I'm trying to make the table view cell's size in <code>systemLayoutSizeFitting</code> equal to the <code>collectionViewContentSize</code>, but it's called before the layout has had a chance to set <code>collectionViewContentSize</code> to the correct value. Here's the order in which these methods are called: </p>
  
  <pre><code>cellForRowAt
  CollectionViewFlowLayout collectionViewContentSize:  (200.0, 500.0) &lt;&lt; incorrect/original value
  **OptionsTableViewCell systemLayoutSizeFitting (200.0, 500.0) &lt;&lt; incorrect/original value**
  CollectionViewFlowLayout collectionViewContentSize:  (200.0, 500.0) &lt;&lt; incorrect/original value
  willDisplay cell
  CollectionViewFlowLayout collectionViewContentSize:  (200.0, 500.0) &lt;&lt; incorrect/original value
  TableViewCell layoutSubviews() collectionViewContentSize.height:  500.0 &lt;&lt; incorrect/original value
  CollectionViewFlowLayout collectionViewContentSize:  (200.0, 500.0) &lt;&lt; incorrect/original value
  CollectionViewFlowLayout layoutAttributesForElements
  CollectionViewFlowLayout collectionViewContentSize:  (450.0, 20.0)
  CollectionViewFlowLayout layoutAttributesForElements
  CollectionViewFlowLayout collectionViewContentSize:  (450.0, 20.0)
  CollectionViewCell systemLayoutSizeFitting
  CollectionViewCell systemLayoutSizeFitting
  CollectionViewCell systemLayoutSizeFitting
  CollectionViewFlowLayout collectionViewContentSize:  (450.0, 20.0)
  CollectionViewFlowLayout layoutAttributesForElements
  CollectionViewFlowLayout collectionViewContentSize:  (450.0, 301.0) &lt;&lt; correct size
  CollectionViewFlowLayout collectionViewContentSize:  (450.0, 301.0) &lt;&lt; correct size
  TableViewCell layoutSubviews() collectionViewContentSize.height:  301.0 &lt;&lt; correct height
  CollectionViewFlowLayout layoutAttributesForElements
  CollectionViewFlowLayout collectionViewContentSize:  (450.0, 301.0) &lt;&lt; correct size
  TableViewCell layoutSubviews() collectionViewContentSize.height:  301.0 &lt;&lt; correct height
  </code></pre>
  
  <p>How can I make my table view cell's height equal to my collection view's tallest item, represented by the layout's <code>collectionViewContentSize</code>?</p>