title: How do I make my collectionView UICollectionViewCell a dynamic height?
body: <p>I have a collectionview and the cells in the collectionview are stretching their height. I used UICollectionViewCompositionalLayout so similar questions asked on this site did not seem to apply.</p>
  <p>Here is where I create my UICollectionViewCompositionalLayout</p>
  <pre><code> private func configureLayout() -&gt; UICollectionViewCompositionalLayout {
          let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
          let item = NSCollectionLayoutItem(layoutSize: itemSize)
          
          let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(400))
          let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
          
          let section = NSCollectionLayoutSection(group: group)
          
          return UICollectionViewCompositionalLayout(section: section)
      }
  </code></pre>
  <p>Here is the View I am trying to display in the cell.</p>
  <pre><code>class PostCell: UICollectionViewCell {
      
      static let reuseIdentifier = String(describing: PostCell.self)
      
      private lazy var textPost : TextPostView = {
          let textPost = TextPostView()
          
          textPost.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(textPost)
          
          textPost.topAnchor.constraint(equalTo: topAnchor).isActive = true
          textPost.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
          textPost.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
          textPost.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
          
          return textPost
      }()
      
      private lazy var mediaPost : MediaPostView = {
          let mediaPost = MediaPostView()
          
          mediaPost.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(mediaPost)
          
          mediaPost.topAnchor.constraint(equalTo: topAnchor).isActive = true
          mediaPost.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
          mediaPost.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
          mediaPost.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
          
          return mediaPost
      }()
      
      private lazy var eventPost : EventPostView = {
          let eventPost = EventPostView()
          
          eventPost.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(eventPost)
          
          eventPost.topAnchor.constraint(equalTo: topAnchor).isActive = true
          eventPost.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
          eventPost.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
          eventPost.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
          
          return eventPost
      }()
      
      func setData(_ presentable: PostPresentable) {
          switch presentable.type {
          case .text:
              eventPost.isHidden = true
              mediaPost.isHidden = true
              textPost.isHidden = false
              textPost.setData(presentable)
          case .media:
              eventPost.isHidden = true
              mediaPost.isHidden = false
              textPost.isHidden = true
              mediaPost.setData(presentable)
          case .event:
              eventPost.isHidden = false
              mediaPost.isHidden = true
              textPost.isHidden = true
              eventPost.setData(presentable)
          }
      }
  }
  </code></pre>
  <p>Here is the TextPostView that I display in the cell</p>
  <pre><code>import Foundation
  import UIKit
  
  class TextPostView: UIView {
      
      lazy var headerView: PostHeaderView = {
          let headerView = PostHeaderView()
          headerView.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(headerView)
          
          let margin: CGFloat = 2
          headerView.topAnchor.constraint(equalTo: topAnchor, constant: margin).isActive = true
          headerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: margin).isActive = true
          headerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: margin).isActive = true
          
          return headerView
      }()
      
      lazy var descriptionView: UILabel = {
          let description = UILabel()
          description.translatesAutoresizingMaskIntoConstraints = false
          description.font = UIFont.preferredFont(forTextStyle: .body)
          description.numberOfLines = 0
          
          
          let headerViewLayoutGuide = headerView.layoutGuide(self)
          
          addSubview(description)
          
          let margin: CGFloat = 8
          
          description.topAnchor.constraint(equalTo: headerViewLayoutGuide.bottomAnchor, constant: margin).isActive = true
          description.leadingAnchor.constraint(equalTo: leadingAnchor,constant: margin).isActive = true
          description.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -margin).isActive = true
          return description
      }()
      
      lazy var footerView: PostFooterView = {
          let footer = PostFooterView()
          footer.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(footer)
          
          let descriptionViewLayoutGuide = descriptionView.layoutGuide(self)
          
          footer.topAnchor.constraint(equalTo: descriptionViewLayoutGuide.bottomAnchor, constant: 8).isActive = true
          footer.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
          footer.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
          footer.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
  
          return footer
      }()
      
      override init(frame: CGRect) {
          super.init(frame: frame)
          initialize()
      }
      
      required init?(coder: NSCoder) {
          super.init(coder: coder)
          initialize()
      }
      
      private func initialize() {
          layer.borderColor = UIColor.gray.cgColor
          layer.borderWidth = 1
          layer.cornerRadius = 16
      }
      
      func setData(_ presentable: PostPresentable) {
          headerView.setData(presentable.header)
          footerView.setData(presentable.footer)
          descriptionView.text = presentable.description
      }
  }
  </code></pre>
  <p>The PostHeaderView that the post uses</p>
  <pre><code>import Foundation
  
  import UIKit
  import SDWebImage
  
  class PostHeaderView: UIView {
      
      private static let horizontalMargin: CGFloat = 8
      private static let iconHeight: CGFloat = 20
      
      private lazy var date: UILabel = {
          let label = UILabel()
          label.font = UIFont.preferredFont(forTextStyle: .caption2)
          label.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(label)
          
          label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: PostHeaderView.horizontalMargin).isActive = true
          label.topAnchor.constraint(equalTo: topAnchor).isActive = true
          
          return label
      }()
      
      private lazy var flairsContainer: UIStackView = {
          let stackView = UIStackView()
          stackView.axis = .horizontal
          stackView.distribution = .fill
          stackView.alignment = .trailing
          stackView.translatesAutoresizingMaskIntoConstraints = false
          
          let dateLayoutGuide = UILayoutGuide()
          let shareLayoutGuide = UILayoutGuide()
          
          addLayoutGuide(dateLayoutGuide)
          addLayoutGuide(shareLayoutGuide)
          addSubview(stackView)
          
          
          dateLayoutGuide.trailingAnchor.constraint(equalTo: date.trailingAnchor).isActive = true
          shareLayoutGuide.leadingAnchor.constraint(equalTo: shareButton.leadingAnchor).isActive = true
          
          stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true
          stackView.leadingAnchor.constraint(equalTo: dateLayoutGuide.trailingAnchor, constant: 16).isActive = true
          stackView.trailingAnchor.constraint(equalTo: shareLayoutGuide.leadingAnchor, constant: -16).isActive = true
          stackView.heightAnchor.constraint(equalToConstant: PostHeaderView.iconHeight).isActive = true
          
          return stackView
      }()
      
      private lazy var title: UILabel = {
          let title = UILabel()
          title.translatesAutoresizingMaskIntoConstraints = false
          title.font = UIFont.preferredFont(forTextStyle: .title1)
      
          
          let avatarLayoutGuide = avatar.layoutGuide(self)
          addSubview(title)
          
          title.leadingAnchor.constraint(equalTo: avatarLayoutGuide.trailingAnchor, constant: 4).isActive = true
          title.trailingAnchor.constraint(equalTo: trailingAnchor, constant: PostHeaderView.horizontalMargin).isActive = true
          title.centerYAnchor.constraint(equalTo: avatarLayoutGuide.centerYAnchor).isActive = true
          
          return title
      }()
      
      private lazy var subHeader: UILabel = {
          let subHeader = UILabel()
          subHeader.translatesAutoresizingMaskIntoConstraints = false
          subHeader.font = UIFont.preferredFont(forTextStyle: .caption1)
          
          let titleLayoutGuide = title.layoutGuide(self)
          addSubview(subHeader)
          
          subHeader.topAnchor.constraint(equalTo: titleLayoutGuide.bottomAnchor, constant: 0).isActive = true
          subHeader.leadingAnchor.constraint(equalTo: titleLayoutGuide.leadingAnchor).isActive = true
          
          return subHeader
      }()
      
      private lazy var checkMark: UIImageView = {
          let checkMark = UIImageView()
          checkMark.translatesAutoresizingMaskIntoConstraints = false
          let image = UIImage(named: &quot;VerifiedBadge&quot;)
          checkMark.image = image
          
          let subHeaderLayoutGuide = subHeader.layoutGuide(self)
          addSubview(checkMark)
          
          checkMark.leadingAnchor.constraint(equalTo: subHeaderLayoutGuide.trailingAnchor).isActive = true
          checkMark.centerYAnchor.constraint(equalTo: subHeaderLayoutGuide.centerYAnchor).isActive = true
          
          return checkMark
      }()
      
      private lazy var menuButton: UIButton = {
          let button = UIButton(type: .custom)
          
          button.translatesAutoresizingMaskIntoConstraints = false
          button.setImage(UIImage(named: &quot;menu&quot;), for: .normal)
          
          addSubview(button)
          
          button.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -PostHeaderView.horizontalMargin).isActive = true
          button.topAnchor.constraint(equalTo: topAnchor).isActive = true
          button.heightAnchor.constraint(equalToConstant: PostHeaderView.iconHeight).isActive = true
          
          return button
      }()
      
      private lazy var shareButton: UIButton = {
          let shareButton = UIButton()
          
          shareButton.translatesAutoresizingMaskIntoConstraints = false
          let buttonImage = UIImage(systemName: &quot;square.and.arrow.up&quot;)?.withRenderingMode(.alwaysTemplate)
          shareButton.setImage(buttonImage, for: .normal)
          shareButton.tintColor = UIColor.black
          
          let menuLayoutGuide = UILayoutGuide()
          addLayoutGuide(menuLayoutGuide)
          addSubview(shareButton)
          
          menuLayoutGuide.leadingAnchor.constraint(equalTo: menuButton.leadingAnchor).isActive = true
          
          shareButton.trailingAnchor.constraint(equalTo: menuLayoutGuide.leadingAnchor, constant: -16).isActive = true
          shareButton.topAnchor.constraint(equalTo: topAnchor).isActive = true
          shareButton.heightAnchor.constraint(equalToConstant: 20).isActive = true
          
          return shareButton
      }()
      
      private lazy var avatar: UIImageView = {
          let imageView = UIImageView()
          imageView.translatesAutoresizingMaskIntoConstraints = false
          imageView.contentMode = .scaleAspectFill
          let imageViewSize: CGFloat = 52
          imageView.layer.cornerRadius = imageViewSize / 2
          imageView.clipsToBounds = true
          
          let dateLayoutGuide = UILayoutGuide()
          addLayoutGuide(dateLayoutGuide)
          addSubview(imageView)
          
          dateLayoutGuide.bottomAnchor.constraint(equalTo: date.bottomAnchor).isActive = true
          
          imageView.heightAnchor.constraint(equalToConstant: imageViewSize).isActive = true
          imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true
          imageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: PostHeaderView.horizontalMargin).isActive = true
          imageView.topAnchor.constraint(equalTo: dateLayoutGuide.bottomAnchor, constant: 2).isActive = true
          imageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
          
          return imageView
      }()
      
      override init(frame: CGRect) {
          super.init(frame: frame)
      }
      
      required init?(coder: NSCoder) {
          super.init(coder: coder)
      }
      
      func setData(_ presentable: PostHeaderPresentable) {
          date.text = presentable.date
          avatar.sd_setImage(with: presentable.avatarImageUrl)
          title.text = presentable.title
          addFlairs(presentable.flairs)
          menuButton.isHidden = false
          shareButton.isHidden = false
          if let subheadline = presentable.subheadline {
              subHeader.isHidden = subheadline.text.isEmpty
              subHeader.text = subheadline.text
              checkMark.isHidden = !subheadline.verified
          } else {
              checkMark.isHidden = true
              subHeader.isHidden = true
          }
      }
      
      private func addFlairs(_ flairImages: [UIImage]) {
          flairsContainer.removeAllArrangedSubviews()
          for flairImage in flairImages {
              let imageView = UIImageView()
              imageView.translatesAutoresizingMaskIntoConstraints = false
              imageView.image = flairImage
              imageView.contentMode = .scaleAspectFill
              
              flairsContainer.addArrangedSubview(imageView)
              
              imageView.heightAnchor.constraint(equalToConstant: PostHeaderView.iconHeight).isActive = true
              imageView.widthAnchor.constraint(equalToConstant: PostHeaderView.iconHeight).isActive = true
          }
      }
      
  }
  </code></pre>
  <p>The PostFooterView</p>
  <pre><code>class PostFooterView: UIView {
      
      private static let horizontalMargin: CGFloat = 8
      private static let verticalMargin: CGFloat = 16
      
      private lazy var location: UILabel = {
          let label = UILabel()
          label.font = UIFont.preferredFont(forTextStyle: .subheadline)
          label.translatesAutoresizingMaskIntoConstraints = false
          
          addSubview(label)
          
          label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -PostFooterView.horizontalMargin).isActive = true
          label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -PostFooterView.verticalMargin).isActive = true
          
          return label
      }()
      
      private lazy var likeButton: UIButton = {
          let button = UIButton()
          button.translatesAutoresizingMaskIntoConstraints = false
          let likeImageSelected = UIImage(named: &quot;Like&quot;)?.withRenderingMode(.alwaysTemplate)
          let likeImage = UIImage(named: &quot;LikeStroke&quot;)?.withRenderingMode(.alwaysTemplate)
          button.setImage(likeImageSelected, for: .selected)
          button.setImage(likeImage, for: .normal)
          button.tintColor = UIColor.black
          
          addSubview(button)
          
          button.leadingAnchor.constraint(equalTo: leadingAnchor, constant: PostFooterView.horizontalMargin).isActive = true
          button.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -PostFooterView.verticalMargin).isActive = true
          return button
      }()
      
      private lazy var dislikeButton: UIButton = {
          let button = UIButton()
          
          button.translatesAutoresizingMaskIntoConstraints = false
          let dislikeImageSelected = UIImage(named: &quot;Dislike&quot;)?.withRenderingMode(.alwaysTemplate)
          let dislikeImage = UIImage(named: &quot;DislikeStroke&quot;)?.withRenderingMode(.alwaysTemplate)
          button.setImage(dislikeImageSelected, for: .selected)
          button.setImage(dislikeImage, for: .normal)
          button.tintColor = UIColor.black
          
          addSubview(button)
          let likeButtonLayoutGuide = likeButton.layoutGuide(self)
          
          button.leadingAnchor.constraint(equalTo: likeButtonLayoutGuide.trailingAnchor, constant: 8).isActive = true
          button.bottomAnchor.constraint(equalTo: likeButtonLayoutGuide.bottomAnchor).isActive = true
          
          return button
      }()
      
      private lazy var navButton : UIButton = {
          let button = UIButton()
          button.translatesAutoresizingMaskIntoConstraints = false
          let navigateImage = UIImage(named: &quot;Navigate&quot;)?.withRenderingMode(.alwaysTemplate)
          button.setImage(navigateImage, for: .normal)
          button.setTitle(&quot;Navigate&quot;, for: .normal)
          button.tintColor = UIColor.black
          button.setTitleColor(UIColor.black, for: .normal)
          
          addSubview(button)
          
          let likeButtonLayoutGuide = likeButton.layoutGuide(self)
          
          topAnchor.constraint(equalTo: button.topAnchor).isActive = true
          button.leadingAnchor.constraint(equalTo: leadingAnchor, constant: PostFooterView.horizontalMargin).isActive = true
          button.bottomAnchor.constraint(equalTo: likeButtonLayoutGuide.topAnchor, constant: -20).isActive = true
          
          return button
      }()
      
      override init(frame: CGRect) {
          super.init(frame: frame)
      }
      
      required init?(coder: NSCoder) {
          super.init(coder: coder)
      }
      
  
      
      func setData(_ presentable: PostFooterPresentable) {
          location.text = presentable.location
          navButton.isHidden = !presentable.showNavigation
          likeButton.isSelected = presentable.reaction == .like
          dislikeButton.isSelected = presentable.reaction == .dislike
      }
  }
  </code></pre>
  <p><a href="https://i.stack.imgur.com/FvFf8.png" rel="nofollow noreferrer">Here is a screenshot of how it looks</a></p>