Self-sizing Table View Cells

In this tutorial, you’ll learn how to enable self-sizing table view cells, as well as how to make them resize on-demand and support Dynamic Type. By Kevin Colligan.

Leave a rating/review
Download materials
Save for later
Share
Update note: Kevin Colligan updated this tutorial for Xcode 10, iOS 12 and Swift 4.2. Joshua Greene wrote the original.

If you’ve ever created custom table view cells before, chances are good that you have spent a lot of time sizing table view cells in code. You may even be familiar with having to calculate, manually, the height of every label, image view, text field — and everything else within the cell.

Frankly, this approach is mind-boggling and error prone. In this self-sizing table view cells tutorial, you’ll learn how to create and size table view cells dynamically to fit their contents. You might be thinking: “That’s going to take a lot of work!” Nope! :]

This tutorial assumes you have a basic familiarity with Auto Layout and UITableView.

Getting Started

Back in the days of iOS 6, Apple introduced a wonderful new technology: Auto Layout. Developers rejoiced; parties commenced in the streets; bands wrote songs to celebrate its greatness…

OK, so that might be a stretch, but it was a big deal.

While it inspired hope for developers, Auto Layout was still cumbersome. Handling Auto Layout manually was, and still is, a great example of the verbosity in iOS development. Interface Builder was also initially quite inefficient when setting up constraints.

Flash forward to now. With all the improvements to Interface Builder, it’s easy to use Auto Layout to create self-sizing table view cells!

A few ins-and-outs aside, all you really have to do is:

  1. Use Auto Layout for the UI elements inside the table view cells.
  2. Set the table view rowHeight to UITableViewAutomaticDimension.
  3. Set the estimatedRowHeight or implement the height estimation delegate method.

But you don’t want to delve into theory right now, do you? You’re ready to get down to coding — so get to business with the project.

Tutorial App Overview

Imagine that you have a movie-crazy client who wants an app to show off a number of favorite film directors and some of their most prominent work. Not just any directors, actually, just their favorite auteurs.

“Auteurs?” you ask, “That sounds French.”

Oui, it is. The auteur theory of film making arose in France in the 1940s and it basically means that the director is the driving creative force behind a film. Not every director is an auteur — only the ones who stamp each film with their individual styles. Think Tarantino or Scorsese. And not everyone agrees with this theory — don’t get your screenwriter friend started. But, the client is always right, so you’re ready to start rolling.

There’s one problem: “We started making the app, but we’re stumped at how to display the content in a table view,” your client admits. “Our table view cells have to resize (gulp!) dynamically! Can you make it work?”

You suddenly feel the urge to don a spiffy beret and start shouting orders!

Auteur

But you don’t need gimmicks to be your client’s iOS auteur — your programming skills will suffice!

First, download the “client’s code” using the Download Materials button at the top or bottom of this tutorial. Expand the zip file and open the Auteur-starter project. (Spoiler alert: You can also open the final Auteur project to see what this app will look like once you’ve finished.)

In the Auteur-starter project, open Main.storyboard in the Views group under the Auteurs project. You’ll see three scenes:

Main.storyboard

From left to right, they are:

  • A top-level navigation controller.
  • AuteurListViewController shows a list of auteurs.
  • AuteurDetailViewController displays the auteur’s films and information about each film.

Build and run. You’ll see the AuteurListViewController displaying a list of auteurs. Select the first auteur, Wes Anderson. The app will segue to the AuteurDetailViewController to display a list of the selected auteur’s films:

View Controllers

Not only is the app missing images of each auteur and each film, the information you are trying to display is also cut off! Each piece of information and image will be a different size, so you can’t just increase the table view cell height and call it a wrap. Your cell heights will need to be dynamic, based on the content of each cell.

You’ll start by implementing the dynamic cell heights in AuteurListViewController.

Creating Self-Sizing Table View Cells

To get dynamic cell heights working properly, you need to create a custom table view cell and set it up with the right Auto Layout constraints.

In the project navigator, select the Views group and press Command-N to create a new file in this group. Create a new Cocoa Touch Class, called AuteurTableViewCell, and make it a subclass of UITableViewCell. Make sure Also create XIB file is unchecked and that the language is set to Swift.

AuteurTableViewCell

First, open AuteurTableViewCell.swift. Then, delete the two automatically generated methods and add the following property:

@IBOutlet weak var bioLabel: UILabel!

Next, open Main.storyboard and select the cell in the table view of the Auteurs scene. In Identity inspector, change Class to AuteurTableViewCell:

AuteurTableViewCell

Drag and drop a new UILabel onto the cell, and set the text to Bio. Set the new label’s Lines property (the number of lines the label can have at most) to 0 in the Attributes inspector. It should look like this:

AuteurTableViewCell Identity Inspector

Setting the number of lines is very important for dynamically sized cells. A label with its number of lines set to 0 will grow based on how much text it is showing. A label with number of lines set to any other number will truncate the text once it’s out of available lines.

Connect the bioLabel outlet of AuteurTableViewCell to the label on the cell. One quick way to do this is to right-click the Cell in the Document Outline, and click-drag from the empty circle to the right of bioLabel under the Outlets list in the pop-up menu to your label that you laid out:

Connect the bioLabel outlet

The trick to get Auto Layout working on a UITableViewCell is to ensure that you have constraints to pin each subview on all sides — that is, each subview should have leading, top, trailing and bottom constraints. Then, the intrinsic height of the subviews will be used to dictate the height of each cell. You’ll do this now.

Note: If you’re not familiar with Auto Layout, or you would like a refresher to understand how to set up Auto Layout constraints, take a look at this tutorial.

Select the bio label and press the Pin button at the bottom of your storyboard. In this menu, select the four dotted lines towards the top of the menu. Next, change the leading and trailing values to 8 and click Add Constraints. It will look like this:

Add Constraints

This ensures that, no matter how big or small the cell may be, the bio label is always:

  • 0 points from the top and bottom margins.
  • 8 points from the leading and trailing margins.

The bio label is connected to the top and bottom margins by 0 points, so Auto Layout can now determine the height of the cell!

  1. Does each subview have constraints that pin all of their sides? Yes
  2. Are there constraints going from the top to the bottom of the contentView? Yes
Review: Does this satisfy the previous Auto Layout criteria?

Awesome, your AuteurTableViewCell is set up! If you build and run the app now, you’ll see that…

One for the blooper reel

…whoa, that’s not right! Cut!

There’s a bit of code you need to write before the cells can become dynamic.