Self-Sizing Table View Cells
Learn how to enable self-sizing table view cells and make them resize on-demand while supporting Dynamic Type. By Chuck Krutsinger .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Self-Sizing Table View Cells
20 mins
- Getting Started
- Looking at the App’s Views
- Creating Self-Sizing Table View Cells
- Adding Constraints to Each Subview
- Configuring the Table View
- Adding a Background
- Adding More User Interfaces
- Adding Views to the Cell
- Adding New Constraints on a Stack View
- Setting the Hugging Priorities
- Populating the New Views
- Expanding Cells
- Implementing Dynamic Type
- Where to Go From Here?
Configuring the Table View
First, you need to configure the table view to use AuteurTableViewCell
.
Open AuteurListViewController.swift. Replace tableView(_:cellForRowAt:)
with the following:
func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
// 1
let cell = tableView.dequeueReusableCell(
withIdentifier: "AuteurCell", for: indexPath)
// 2
if let cell = cell as? AuteurTableViewCell {
let auteur = auteurs[indexPath.row]
cell.bioLabel.text = auteur.bio
}
return cell
}
The code above is pretty straightforward. In it, you:
- Dequeue an AuteurCell. This is the identifier from the storyboard.
- Set the bio text from the current row of the
auteurs
array and return the cell.
Still in AuteurListViewController.swift, add these two lines of code at the end of viewDidLoad()
:
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 600
Setting the row height to UITableView.automaticDimension
tells the table view to use the Auto Layout constraints and the contents of its cells to determine each cell’s height.
For the table view to do this, you must also provide estimatedRowHeight
. In this case, 600
is a roughly estimated value that works well in this particular instance.
For your own projects, you’ll need to determine a good estimate of the average height. Any value will work, but the accuracy of the estimate affects the efficiency of the layout.
Build and run. You’ll now see each auteur’s full bio.
That looks better! But wouldn’t a moody dark background make this app even more dramatic?
Adding a Background
Open Main.storyboard. In the table view of Auteurs Scene, select AuteurCell. In the Attributes inspector, click the Background drop-down menu:
Select AuteursBackground for a nice black-ish background — pure black is not cool enough for auteurs. :]
In the same scene, set the same background color for Table View and View.
Now, select Bio Label. Set the text color to System Gray 4 Color so the text will stand out against the new background color.
You want the navigation header to have the same background color, so open AppDelegate.swift and paste this code after var window: UIWindow?
:
func applicationDidFinishLaunching(_ application: UIApplication) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = UIColor(named: "AuteursBackground")
appearance.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.systemGray2
]
appearance.largeTitleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.systemGray2
]
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
The code above defines the appearance of UINavigationController
throughout your app. It will give it an opaque background using AuteursBackground as the background color and System Gray 2 as the text color.
Build and run. It’ll look like this:
Such drama!
Adding More User Interfaces
It’s nice to read the entire bio of each artist, but there’s more data to show: the artist’s name, image and the source of the information. These additional pieces of data will make the app look much better.
Your next goal is to add an image view to AuteurTableViewCell
, a label for the auteur’s name and a label for the source of the photo.
Open AuteurTableViewCell.swift. Add the following properties:
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var sourceLabel: UILabel!
@IBOutlet weak var auteurImageView: UIImageView!
These UI elements will display the auteur’s name, information source and image.
Open Main.storyboard. In bio label, remove the constraints you added earlier.
You can select and remove all four constraints in the Document Outline.
Before adding more elements, you’ll want some elbow room. Select AuteurCell from the Document Outline. Then, in the Size inspector, change the row height to 450.
Adding Views to the Cell
Now, you’ll fill up the space you just added. From the Library, drag:
- An Image View into the cell.
- A Label into the cell. Set the text to Name and color to System Gray 4.
- Another Label into the cell. Set the text to Source and font size to System 13.0 and color to System Gray 4.
Next, connect the outlets for the new image view and labels:
Adding New Constraints on a Stack View
Instead of creating constraints for every view, you’re going to use a stack view to limit the number of constraints. Embed the labels and image view from AuteurTableViewCell
in a stack view.
In the Document Outline, order the elements from top to bottom as follows within the stack view:
- Image View
- Name Label
- Bio Label
- Source Label
Select the stack view. In the Attributes inspector, set the alignment to Fill and spacing to 8.
Add the following constraints to the stack view:
- 0 points from the top and bottom margins.
- 8 points from the leading and trailing margins.
Add the following constraints to the image view:
- 1:1 width-to-height aspect ratio.
Just like that, you’ve pinned the edges of the stack view its superview’s edges. Plus, you’ve ensured a 1:1 width-to-height aspect ratio with the image view.
However, the labels have equal vertical content hugging priority and it’s ambiguous to Auto Layout to prioritize which label should shrink or expand over the other. You’ll inform Auto Layout about this next.
Setting the Hugging Priorities
You’ll set the hugging vertical priorities for the name label and bio label.
Select Name Label and, in the Size inspector, scroll down until you see Content Hugging Priority.
By default, horizontal and vertical content hugging priorities are 251. Change the name label’s vertical content hugging priority to 253.
Now, select the Bio Label and set its Vertical priority to 252.
Not exactly. Setting a higher priority on content hugging means the view will resist growing larger than its intrinsic size. You told the storyboard to make your cell 450 points tall, which is larger than the intrinsic size of your views. Setting a vertical content hugging priority tells Xcode which view to expand if it needs to fill the space.
Not exactly. Setting a higher priority on content hugging means the view will resist growing larger than its intrinsic size. You told the storyboard to make your cell 450 points tall, which is larger than the intrinsic size of your views. Setting a vertical content hugging priority tells Xcode which view to expand if it needs to fill the space.
You have the layout of your table view cell without all that much cognitive efforts. However, your UI wouldn’t be complete without populating the new views.