UICollectionView
cell sizing
dynamic layout
iOS development
Swift programming

Dynamic cell width of UICollectionView depending on label width

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When collection view cells behave like tags, chips, or pills, fixed widths usually look wrong. The standard fix is to size each cell from the label text plus padding, either by measuring the string manually in sizeForItemAt or by using self-sizing cells with Auto Layout.

Manual sizing with sizeForItemAt

If your cell height is fixed and only the width should change, explicit measurement is often the most predictable approach. Measure the text using the same font as the label, add horizontal padding, and return the result from the flow layout delegate.

swift
1import UIKit
2
3final class TagsViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
4    @IBOutlet private weak var collectionView: UICollectionView!
5
6    private let items = ["Swift", "UICollectionView", "Dynamic Width", "iOS"]
7    private let cellFont = UIFont.systemFont(ofSize: 16, weight: .medium)
8
9    override func viewDidLoad() {
10        super.viewDidLoad()
11        collectionView.dataSource = self
12    }
13
14    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
15        items.count
16    }
17
18    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
19        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TagCell", for: indexPath) as! TagCell
20        cell.titleLabel.font = cellFont
21        cell.titleLabel.text = items[indexPath.item]
22        return cell
23    }
24
25    func collectionView(
26        _ collectionView: UICollectionView,
27        layout collectionViewLayout: UICollectionViewLayout,
28        sizeForItemAt indexPath: IndexPath
29    ) -> CGSize {
30        let text = items[indexPath.item] as NSString
31        let textWidth = text.size(withAttributes: [.font: cellFont]).width
32        let horizontalPadding: CGFloat = 24
33        let height: CGFloat = 36
34        return CGSize(width: ceil(textWidth + horizontalPadding), height: height)
35    }
36}

This is simple and fast. The main rule is consistency: the measurement font must exactly match the label font, or your widths will be slightly off.

Build the cell with real padding

The label should not be pinned edge-to-edge. Give it internal padding through constraints so the measured width and the visible layout agree.

swift
1final class TagCell: UICollectionViewCell {
2    let titleLabel = UILabel()
3
4    override init(frame: CGRect) {
5        super.init(frame: frame)
6
7        contentView.backgroundColor = .systemBlue
8        contentView.layer.cornerRadius = 18
9
10        titleLabel.translatesAutoresizingMaskIntoConstraints = false
11        titleLabel.textColor = .white
12        titleLabel.numberOfLines = 1
13        contentView.addSubview(titleLabel)
14
15        NSLayoutConstraint.activate([
16            titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12),
17            titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -12),
18            titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
19            titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8)
20        ])
21    }
22
23    required init?(coder: NSCoder) {
24        fatalError("init(coder:) has not been implemented")
25    }
26}

In this setup, the 24 points of horizontal padding in sizeForItemAt matches the 12 + 12 leading and trailing constraints. That keeps the measured width and actual rendered width aligned.

Self-sizing cells with Auto Layout

If you prefer less manual measurement, UICollectionViewFlowLayout can let the cell size itself. This is useful when width and height may both change or when the label can wrap.

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3
4    if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
5        layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
6        layout.minimumInteritemSpacing = 8
7        layout.minimumLineSpacing = 8
8    }
9}

With this approach, Auto Layout uses the label constraints and intrinsic content size to derive the final cell size. It is convenient, but it can be less predictable than explicit measurement if the layout is dense or performance-sensitive.

For single-line tag layouts, manual sizing is often easier to control. For more complex cells, self-sizing is usually cleaner.

Common Pitfalls

The most common problem is measuring the text with one font and displaying it with another. Even a small font difference causes clipping or extra whitespace.

Another issue is forgetting that UICollectionViewFlowLayout caches layout information. If the text changes, call collectionView.collectionViewLayout.invalidateLayout() or reload the affected items so the cell widths are recalculated.

Constraint problems inside the cell also cause confusing results. If the label is missing leading and trailing constraints, Auto Layout may produce an unexpected width or fall back to a default size.

Finally, do not mix manual sizeForItemAt sizing with automaticSize unless you are very deliberate about which one owns the layout. Pick one sizing strategy per section or per collection view to avoid inconsistent behavior.

Summary

  • For label-driven cell widths, manual measurement in sizeForItemAt is usually the most predictable solution.
  • Measure with the same font the label actually uses and add the same padding used in constraints.
  • Self-sizing cells with automaticSize work well when Auto Layout should own the full cell size.
  • Invalidate the layout when content changes so widths are recomputed.
  • Keep one clear sizing strategy instead of mixing competing layout approaches.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.