UICollectionView
iOS development
Swift
grid layout
mobile app development

UICollectionView Set number of columns

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

UICollectionView does not have a direct numberOfColumns property. The number of columns comes from layout math: item width, section insets, inter-item spacing, and the collection view's current width.

In practice, you choose a layout strategy and compute itemSize so that a row fits exactly the number of columns you want. For most grid screens, UICollectionViewFlowLayout plus UICollectionViewDelegateFlowLayout is enough.

Calculate Item Width From The Available Space

The basic formula is:

text
availableWidth = collectionWidth - leftInset - rightInset - totalSpacing
itemWidth = availableWidth / numberOfColumns

In Swift, that often looks like this:

swift
1import UIKit
2
3final class GridViewController: UIViewController, UICollectionViewDelegateFlowLayout {
4    @IBOutlet private weak var collectionView: UICollectionView!
5
6    private let columns: CGFloat = 3
7    private let spacing: CGFloat = 8
8    private let sectionInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
9
10    func collectionView(
11        _ collectionView: UICollectionView,
12        layout collectionViewLayout: UICollectionViewLayout,
13        sizeForItemAt indexPath: IndexPath
14    ) -> CGSize {
15        let totalSpacing = sectionInsets.left + sectionInsets.right + (columns - 1) * spacing
16        let availableWidth = collectionView.bounds.width - totalSpacing
17        let itemWidth = floor(availableWidth / columns)
18        return CGSize(width: itemWidth, height: itemWidth)
19    }
20
21    func collectionView(
22        _ collectionView: UICollectionView,
23        layout collectionViewLayout: UICollectionViewLayout,
24        minimumInteritemSpacingForSectionAt section: Int
25    ) -> CGFloat {
26        spacing
27    }
28
29    func collectionView(
30        _ collectionView: UICollectionView,
31        layout collectionViewLayout: UICollectionViewLayout,
32        insetForSectionAt section: Int
33    ) -> UIEdgeInsets {
34        sectionInsets
35    }
36}

That is the core pattern. Once the width is correct, the number of columns is effectively fixed.

Make The Column Count Dynamic

Many apps change the number of columns by width class or screen size. The simplest approach is to compute the count from the current bounds:

swift
1func currentColumnCount(for width: CGFloat) -> CGFloat {
2    if width >= 900 { return 4 }
3    if width >= 600 { return 3 }
4    return 2
5}

Then use that value inside sizeForItemAt. This works well for rotation, iPad split view, and compact versus regular layouts.

Invalidate Layout On Size Changes

If the collection view width changes, the old cell sizes may no longer match the desired column count. That is why size changes should trigger a layout invalidation or reload.

swift
1override func viewWillLayoutSubviews() {
2    super.viewWillLayoutSubviews()
3    collectionView.collectionViewLayout.invalidateLayout()
4}

Without invalidation, rotation bugs often show up as clipped cells, leftover spacing, or one extra item wrapped onto the next row.

When Compositional Layout Is Better

If the grid is part of a more complex screen, compositional layout can express columns more directly:

swift
1let item = NSCollectionLayoutItem(
2    layoutSize: .init(widthDimension: .fractionalWidth(1.0 / 3.0),
3                      heightDimension: .fractionalWidth(1.0 / 3.0))
4)
5let group = NSCollectionLayoutGroup.horizontal(
6    layoutSize: .init(widthDimension: .fractionalWidth(1.0),
7                      heightDimension: .fractionalWidth(1.0 / 3.0)),
8    subitems: [item]
9)

That approach is powerful, but for a straightforward grid, flow layout is still easier to reason about.

Rotation And Size Changes

A column calculation that works in portrait can break in landscape if the collection view width changes and the layout is not invalidated. That is why grid code should always assume the width is dynamic, especially on iPad and during split-view resizing.

Common Pitfalls

  • Looking for a built-in numberOfColumns property that does not exist.
  • Forgetting to subtract section insets and inter-item spacing from the available width.
  • Calculating from frame too early instead of using the current bounds during layout.
  • Not invalidating the layout when the collection view width changes.
  • Returning widths with fractional leftovers that cause subtle wrapping or spacing issues.

Summary

  • 'UICollectionView columns are controlled by layout math, not a dedicated property.'
  • Compute item width from the collection view width, insets, and spacing.
  • Use UICollectionViewDelegateFlowLayout for most standard grids.
  • Recalculate or invalidate the layout when size changes occur.
  • Use compositional layout when the screen needs a more advanced grid definition.

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.