How to create a UICollectionView with cells that size to fit content

Oscar de la Hera Gomez
Two flowers that represent Swift and XCode with the text "Dynamic UICollectionViewCell Height" beneath them.

A step by step guide on implementing a UICollectionViewCompositionalLayout where UICollectionViewCells dynamically adjust to fit text content in Swift.

The following tutorial uses our Open Source Swift Starter Project to walk you through how to create a UICollectionView similar to iMessage where UICollectionViewCells dynamically adapt their height to elegantly display content.

An image showing what the result looks like on an iPhone in Portrait and Landscape.

The results of this tutorial.

As demonstrated above, tutorial uses the example of a UICollectionViewCell that holds between 1-3 labels, depending on its index; to demonstrate that the algorithm adapts the UICollectionViewCells height to fit the text of the labels.

If you wish to learn how to create data-driven UICollectionViews, please consult the tutorial below before adapting Step Four to your solution - data should be applied as part of the configuration of the Data Source.

We recommend that you clone our Open Source Swift Starter Project, checking out the main branch and carrying out the steps below. The changes can be found on the tutorial/uicollectionview/dynamic-cell-size branch.

git clone git@github.com:delasign/swift-starter-project.git

Step One: Add the Content

A screenshot of Xcode showing the content that we created as part of the tutorial.

The following step is intended to create three sample strings that will be consumed by the application.

This step builds on our Localization tutorial which is available below and follows our methodology that allows apps to be created for multiple languages.

A | Create the UIContent

A screenshot of XCode showing the updated UIContent.swift file.

Add your content to the UIContent file.

In our case we have added two additional sample strings to the existing sample string.

B | Add Strings

A screenshot of Xcode showing the updated strings in the English localization file.

Add the relevant strings to en.json and es.json; or the necessary language files for the app to operate.

Step Two: Add the Attributed Styles

A screenshot of Xcode showing our updated Attributed style which we created in a prior tutorial, which is linked below.

As part of this step, we modified a previously created custom attributed style.

For more information on how to create these or why we use them, please consult the articles below.

Step Three: Create the UICollectionViewCell

A screenshot of the three files that we created for the DynamicLabelCell. The code and instructions behind these is found below.

The following step creates a UICollectionViewCell whose content view holds three labels that are initially empty.

It is important to note that for this process to work, the labels or layout must only be setup once and be cleared on prepareForReuse.

If you setup the label or layout every time a UICollectionViewCell is reused or reloaded, it will not work.

This implies that if you use a UICollectionViewCell that adapts its layout based on content (i.e. sometimes uses an image or a button, sometimes both and sometimes neither) a custom algorithm must be applied in Step Three, Part C to make sure that only the necessary views are considered.

This content will be updated through a UICollectionView.CellRegistration method in Step Four, Part C.

A | Create the declaration file

A screenshot of the newly created DynamicLabelCell.swift file in Xcode. Code available below.

Under UI/Components, create a new folder called DynamicLabelCell.

Within the newly created DynamicLabelCell folder, create a new file called DynamicLabelCell.swift and paste in the code below.

B | Create the UI file

A screenshot of the newly created DynamicLabelCell+UI.swift file in XCode. Code available below.

In the newly created DynamicLabelCell folder, create a new file called DynamicLabelCell+UI.swift, and paste in the code below.

Please note that in order for the dynamic sizing to work, at least one piece of content (i.e. an image or a label) must be constrained to the top and bottom of the content view.

C | Create the Update file

A screenshot of the DynamicLabelCell+Update.swift file in Xcode. Code available below.

In the newly created DynamicLabelCell folder, create a new file called DynamicLabelCell+Update.swift, and paste in the code below.

Please note that the update function is where we recommend that you adapt the cell to the new content; and alter constraints so that everything looks right.

Step Four: Create the UICollectionView

A screenshot of Xcode showing the files that we created as part of this step. They are outlined below.

The following step declares the UICollectionView and associated variables within our CustomUIView and configures the UICollectionView to work with the DynamicLabelCell using a UICollectionViewCompositionalLayout.

For examples of standard, fixed sized data-driven UICollectionViews or a UICollectionView that uses multiple cells within different sections, please consult the articles below.

Please note that we removed all UILabel functionality from the CustomUIView and the removal of that functionality is not documented in this tutorial.

A | Declare the UICollectionView, sections and data source

A screenshot of the CustomUIView.swift file with the declarations for the UIColllectionview, sections and data source. We have highlighted where we call configureDataSource in the initializer. Code available below.

In CustomUIView.swift, declare the UICollectionView, sections and data source using the code below.

Make sure that you call configureDataSource, in the init(frame: CGRect) function. The configureDataSource function will be created in part C of this step.

B | Setup the UI

A screenshot of CustomUIView+UI.swift, showing how we added the UICollectionView to the CustomUIView and registered the DynamicLabelCell. Code available below.

In CustomUIView+UI.swift setup the UICollectionView.

Sample code on how to achieve this is available below.

Please note that the setupCollectionView cannot be wrapped in a DispatchQueue.main.async as it will cause the configureDataSource to crash due to the collectionView being unwrapped as nil.

Additionally, we choose to register the cells in this step but we have since learned that the registration of cells is not necessary in UICollectionViewCompositionalLayouts.

C | Create the UICollectionView Extension

A screenshot of the CustomUIView+CollectionView.swift file in XCode. Code available below.

In the CustomUIView folder, create a new file CustomUIView+CollectionView.swift and paste in the code below.

  • The createLayout function is consumed by the UICollectionView when we set it up the UI extension and is responsible for dictating the size of the UICollectionViewCells and the way they are laid out. In this example, the layout takes in an estimated height - which will adapt based on the content. Please note that this estimated height should neither be too big or too small.
  • The configureDataSource function is responsible for creating the data source for the UICollectionView, determining how the cells update in the UICollectionView and creating a link between the data source and the UICollectionView.

For a tutorial on creating a UICompositionalLayout that uses multiple sections and UICollectionViewCells, consult the article below.

For more information on Compositional Layouts, consult the article below.

Step Five: Invalidate the layout

A screenshot of Xcode showing how we invalidated the UICollectionView layout when the content updates through the onContentUpdate function in the CustomUIView+Update.swift file.

In order for the algorithm to work, the UICollectionView must reload its data when the content updates.

To do this invalidate the layout in the onContentUpdate function in CustomUIView+Update.swift through code similar to the one provided below.

self.collectionView.collectionViewLayout.invalidateLayout()

Step Six: Verify

An image showing what the result looks like on an iPhone in Portrait and Landscape.

Run the app and you will see that the UICollectionView cells adapt to the size of the content, in English and Spanish; and in any orientation of your liking.

Any Questions?

We are actively looking for feedback on how to improve this resource. Please send us a note to inquiries@delasign.com with any thoughts or feedback you may have.
delasign logo

Book a Free Consultation.

An icon of an email.

Click here to email us.

Fill in the details below to book a free consultation or to let us know about something else. Whatever it is, we are here to help.

How can we help you ?

Contact Details