iOS development
Swift programming
UICollectionView
iOS UI components
mobile app development

Creating a UICollectionView programmatically

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

Creating a UICollectionView programmatically gives you full control over layout, registration, and constraints without relying on Storyboards. The pattern is straightforward once you break it into parts: create a layout, create the collection view, register a cell, and implement the data source and delegate methods. Programmatic setup is especially useful in reusable components, modular UI code, and dynamic layouts.

Start with a Layout

Every collection view needs a layout object. A UICollectionViewFlowLayout is the simplest starting point.

swift
1import UIKit
2
3let layout = UICollectionViewFlowLayout()
4layout.scrollDirection = .vertical
5layout.minimumLineSpacing = 12
6layout.minimumInteritemSpacing = 12
7layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)

This layout decides spacing, direction, and basic item placement.

Create the Collection View

In a view controller, instantiate the collection view with the layout and constrain it to the parent view.

swift
1import UIKit
2
3final class ColorsViewController: UIViewController {
4    private let items = ["Red", "Blue", "Green", "Orange"]
5    private var collectionView: UICollectionView!
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9        view.backgroundColor = .systemBackground
10
11        let layout = UICollectionViewFlowLayout()
12        layout.scrollDirection = .vertical
13        layout.minimumLineSpacing = 12
14        layout.minimumInteritemSpacing = 12
15        layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
16
17        collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
18        collectionView.translatesAutoresizingMaskIntoConstraints = false
19        collectionView.backgroundColor = .systemBackground
20        collectionView.dataSource = self
21        collectionView.delegate = self
22        collectionView.register(ColorCell.self, forCellWithReuseIdentifier: ColorCell.reuseID)
23
24        view.addSubview(collectionView)
25        NSLayoutConstraint.activate([
26            collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
27            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
28            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
29            collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
30        ])
31    }
32}

That is the core setup. The collection view exists, is attached to the view hierarchy, and knows which cell class to reuse.

Build a Custom Cell

A custom cell keeps presentation logic out of the controller.

swift
1import UIKit
2
3final class ColorCell: UICollectionViewCell {
4    static let reuseID = "ColorCell"
5
6    private let titleLabel = UILabel()
7
8    override init(frame: CGRect) {
9        super.init(frame: frame)
10        contentView.backgroundColor = .systemBlue
11        contentView.layer.cornerRadius = 12
12
13        titleLabel.translatesAutoresizingMaskIntoConstraints = false
14        titleLabel.textColor = .white
15        titleLabel.font = .preferredFont(forTextStyle: .headline)
16
17        contentView.addSubview(titleLabel)
18        NSLayoutConstraint.activate([
19            titleLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
20            titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
21        ])
22    }
23
24    required init?(coder: NSCoder) {
25        fatalError("init(coder:) has not been implemented")
26    }
27
28    func configure(with text: String) {
29        titleLabel.text = text
30    }
31}

Programmatic cells are a good place to add subviews, Auto Layout constraints, and styling.

Implement the Data Source

Now provide the item count and cell configuration.

swift
1extension ColorsViewController: UICollectionViewDataSource {
2    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
3        items.count
4    }
5
6    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
7        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ColorCell.reuseID, for: indexPath) as! ColorCell
8        cell.configure(with: items[indexPath.item])
9        return cell
10    }
11}

Without these methods, the collection view appears but shows no content.

Size the Items

If you use UICollectionViewFlowLayout, implement UICollectionViewDelegateFlowLayout for item sizing.

swift
1extension ColorsViewController: UICollectionViewDelegateFlowLayout {
2    func collectionView(
3        _ collectionView: UICollectionView,
4        layout collectionViewLayout: UICollectionViewLayout,
5        sizeForItemAt indexPath: IndexPath
6    ) -> CGSize {
7        let width = (collectionView.bounds.width - 44) / 2
8        return CGSize(width: width, height: 120)
9    }
10}

This creates a simple two-column grid with spacing already accounted for.

When Programmatic Setup Helps Most

Code-based setup is especially useful when:

  • the UI is reused across modules
  • layout changes depend on runtime configuration
  • the project avoids Storyboards by convention
  • the collection view lives inside a custom reusable view

It also makes review diffs cleaner because the behavior is visible in Swift code instead of Interface Builder metadata.

Common Pitfalls

  • Forgetting to register the cell class or nib before dequeueing cells.
  • Adding the collection view without disabling autoresizing masks or adding constraints.
  • Implementing the collection view but forgetting to set the dataSource and delegate.
  • Hardcoding item sizes without accounting for section insets and spacing.
  • Putting too much presentation logic into the view controller instead of a custom cell.

Summary

  • A programmatic UICollectionView starts with a layout, a registered cell, and data source wiring.
  • 'UICollectionViewFlowLayout is the easiest default layout for grids and lists.'
  • Custom cells keep styling and subview configuration organized.
  • Auto Layout constraints are required if the collection view is created in code.
  • Programmatic setup is ideal when you want precise control and reusable UI code.

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.