UICollectionView
iOS development
Swift programming
cell alignment
mobile app design

How to center horizontally UICollectionView Cells?

Master System Design with Codemia

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

Introduction

Centering UICollectionView cells horizontally usually means one of two things: centering the whole row when the content is narrower than the collection view, or snapping the visible item into the horizontal center while scrolling. The simpler case is row centering with UICollectionViewFlowLayout and calculated section insets. The correct solution depends on which of those two layouts you actually want.

Center a Single Row With Section Insets

If your cells are arranged in one horizontal row and the total content width is smaller than the collection view width, calculate left and right insets so the row sits in the center.

swift
1import UIKit
2
3final class CenteredViewController: UIViewController, UICollectionViewDelegateFlowLayout {
4    @IBOutlet private weak var collectionView: UICollectionView!
5
6    private let items = Array(0..<5)
7    private let itemWidth: CGFloat = 80
8    private let itemHeight: CGFloat = 80
9    private let spacing: CGFloat = 12
10
11    func collectionView(_ collectionView: UICollectionView,
12                        layout collectionViewLayout: UICollectionViewLayout,
13                        sizeForItemAt indexPath: IndexPath) -> CGSize {
14        CGSize(width: itemWidth, height: itemHeight)
15    }
16
17    func collectionView(_ collectionView: UICollectionView,
18                        layout collectionViewLayout: UICollectionViewLayout,
19                        insetForSectionAt section: Int) -> UIEdgeInsets {
20        let totalItemWidth = CGFloat(items.count) * itemWidth
21        let totalSpacingWidth = CGFloat(max(items.count - 1, 0)) * spacing
22        let contentWidth = totalItemWidth + totalSpacingWidth
23        let horizontalInset = max((collectionView.bounds.width - contentWidth) / 2, 0)
24
25        return UIEdgeInsets(top: 0, left: horizontalInset, bottom: 0, right: horizontalInset)
26    }
27
28    func collectionView(_ collectionView: UICollectionView,
29                        layout collectionViewLayout: UICollectionViewLayout,
30                        minimumLineSpacingForSectionAt section: Int) -> CGFloat {
31        spacing
32    }
33}

This approach works well when every cell has the same size and the row should simply be visually centered.

Recalculate After Layout Changes

Collection view width can change after rotation, split-view resizing, or dynamic layout updates. If your centering depends on bounds.width, invalidate the layout when the size changes.

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

Without this, the insets may be correct at launch but wrong after orientation changes.

Centering Variable-Width Cells

If cells have dynamic widths, you still use the same idea, but the total content width must be calculated from the actual item sizes. In that case, a custom flow layout or cached size calculation is often cleaner than hardcoding one width value.

The important point is that centering is based on total row width, not on setting arbitrary fixed insets and hoping they happen to look right on every device.

Distinguish Row Centering From Scroll Snapping

Sometimes developers say "center horizontally" when they actually mean "keep the currently focused cell in the middle while scrolling." That is a different problem.

For a carousel-like effect, you usually implement a custom layout or override targetContentOffset so the nearest cell snaps to center after scrolling.

That behavior is not achieved by section insets alone. Insets center the content block. Snapping centers the visible item.

Make Sure the Delegate Method Is Actually Used

If UICollectionViewDelegateFlowLayout methods do not seem to run, verify:

  • the collection view's layout is a UICollectionViewFlowLayout
  • the delegate is assigned
  • another custom layout is not replacing the flow layout logic

This matters because developers often write insetForSectionAt or sizeForItemAt correctly, but the methods never run due to delegate or layout configuration issues.

Common Pitfalls

The most common mistake is using fixed left and right insets without calculating the real content width. That may look centered on one device size and wrong on another.

Another issue is forgetting to invalidate the layout after size changes. Rotation often reveals that bug immediately.

Developers also frequently confuse row centering with carousel snapping. They require different techniques.

Finally, if UICollectionViewDelegateFlowLayout methods are not being called, check the delegate connection and confirm the collection view is actually using a flow layout.

Summary

  • For a centered horizontal row, calculate section insets from the collection view width and total content width.
  • Recalculate or invalidate the layout when the view size changes.
  • Use a custom snapping layout when the goal is centered scrolling behavior, not just centered content.
  • Verify that UICollectionViewDelegateFlowLayout methods are actually active.
  • Base centering on measured sizes, not hardcoded device-specific inset guesses.

Course illustration
Course illustration

All Rights Reserved.