UILabel
dynamic text
iOS development
text adjustment
Swift programming

Adjust UILabel height depending on the text

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A UILabel should usually grow to fit its text instead of forcing the text into a fixed height. On iOS, the most reliable solution is to let Auto Layout determine the height from constraints and multiline settings, then fall back to manual measurement only when you are building frames yourself.

Core Sections

Let Auto Layout do the work first

If you are using constraints, start with the simplest correct configuration:

  • set numberOfLines = 0
  • constrain leading and trailing edges
  • give the label a top anchor or vertical position
  • avoid a fixed height constraint unless you really mean it
swift
1import UIKit
2
3final class ExampleViewController: UIViewController {
4    private let messageLabel: UILabel = {
5        let label = UILabel()
6        label.translatesAutoresizingMaskIntoConstraints = false
7        label.numberOfLines = 0
8        label.font = .systemFont(ofSize: 17)
9        label.text = "A long piece of text that should wrap across multiple lines and expand the label height automatically."
10        return label
11    }()
12
13    override func viewDidLoad() {
14        super.viewDidLoad()
15        view.backgroundColor = .systemBackground
16        view.addSubview(messageLabel)
17
18        NSLayoutConstraint.activate([
19            messageLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
20            messageLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
21            messageLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20)
22        ])
23    }
24}

With this setup, the label’s intrinsic content size plus the width constraints determine the correct height. In many cases, that is all you need.

Avoid fixed-height constraints

The most common reason a label fails to expand is that a height constraint or container layout is fighting Auto Layout. If a label has numberOfLines = 0 but also a height of 44, the text will still be clipped because the fixed height wins.

If the label lives inside a reusable cell or stack view, inspect the surrounding constraints as well. Sometimes the label is configured correctly but the parent view has an insufficient height or ambiguous vertical compression priorities.

Measure text manually when using frames

If you are laying out subviews manually, calculate the size that fits the available width and then assign the frame.

swift
1import UIKit
2
3let label = UILabel()
4label.numberOfLines = 0
5label.font = .systemFont(ofSize: 17)
6label.text = "Manual layout still needs a measured height."
7
8let maxWidth: CGFloat = 280
9let size = label.sizeThatFits(CGSize(width: maxWidth, height: .greatestFiniteMagnitude))
10label.frame = CGRect(x: 20, y: 40, width: maxWidth, height: size.height)

sizeThatFits is a good default for manual layout because it respects the label’s font, wrapping behavior, and text content.

Use preferredMaxLayoutWidth when needed

Modern Auto Layout usually infers width from constraints, but older layouts or unusual container setups may need preferredMaxLayoutWidth so the label knows where wrapping should occur.

That is especially relevant when the label’s width is not fully known during the first layout pass. If text truncates or the height looks wrong even though numberOfLines is zero, missing width information is often the cause.

Dynamic Type and reusable cells

If the label participates in Dynamic Type, its height can change after the content size category changes. In table and collection view cells, this means the cell layout must also be able to expand.

A common pattern is:

  • enable multiline labels
  • use self-sizing cells or explicit invalidation
  • avoid hard-coded row heights for text-heavy content

This keeps accessibility settings from breaking the layout.

If you are inside a table or collection cell

The label’s height is only one part of the problem. The container must also be able to grow. In a table view, for example, self-sizing rows are often the missing step.

swift
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 80

Without container support, the label may calculate the right height but still be clipped by a cell that refuses to resize.

Common Pitfalls

  • Setting numberOfLines = 0 but also keeping a fixed height constraint that prevents the label from expanding.
  • Measuring the text before the available width is known, which leads to incorrect height calculations.
  • Fixing the label itself while forgetting that the containing cell or view still has a hard-coded height.
  • Ignoring Dynamic Type, which causes layouts to break when users increase text size.
  • Mixing manual frames and Auto Layout on the same label without a clear reason, which often creates confusing layout conflicts.

Summary

  • The preferred solution is usually Auto Layout with numberOfLines = 0 and no fixed height.
  • Manual measurement with sizeThatFits is appropriate when you are doing frame-based layout.
  • Width constraints matter because label height depends on wrapping width.
  • In reusable cells, the container must also support dynamic height.
  • Most UILabel sizing bugs come from conflicting constraints, not from UILabel itself.

Course illustration
Course illustration

All Rights Reserved.