Swift
UICollectionView
Device Rotation
Layout Update
iOS Development

Swift How to refresh UICollectionView layout after rotation of the device

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

When a device rotates, a UICollectionView often needs more than a simple redraw. If cell sizes depend on the available width, you need to invalidate the layout and recompute item sizes after the new bounds are known.

Invalidate the Layout During the Size Transition

The standard hook for rotation-aware updates is viewWillTransition(to:with:). Invalidate the layout there so the collection view stops using cached geometry from the old orientation.

swift
1import UIKit
2
3final class GridViewController: UIViewController {
4    @IBOutlet private weak var collectionView: UICollectionView!
5
6    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
7        super.viewWillTransition(to: size, with: coordinator)
8
9        coordinator.animate(alongsideTransition: { _ in
10            self.collectionView.collectionViewLayout.invalidateLayout()
11        })
12    }
13}

That tells the layout system that previously calculated attributes are no longer valid.

Recompute Item Sizes from Current Bounds

Invalidation alone is not enough if your sizing logic still uses stale width values. If you use UICollectionViewDelegateFlowLayout, compute sizes from the collection view's current bounds.

swift
1extension GridViewController: UICollectionViewDelegateFlowLayout {
2    func collectionView(
3        _ collectionView: UICollectionView,
4        layout collectionViewLayout: UICollectionViewLayout,
5        sizeForItemAt indexPath: IndexPath
6    ) -> CGSize {
7        let columns: CGFloat = collectionView.bounds.width > collectionView.bounds.height ? 4 : 2
8        let spacing: CGFloat = 10
9        let totalSpacing = spacing * (columns - 1)
10        let width = (collectionView.bounds.width - totalSpacing) / columns
11
12        return CGSize(width: width, height: width)
13    }
14}

This recalculates cell size using the post-rotation width instead of a hardcoded portrait measurement.

Update the Flow Layout in viewDidLayoutSubviews

If you set itemSize directly on a UICollectionViewFlowLayout, update it in viewDidLayoutSubviews(), which runs after the new bounds are final.

swift
1override func viewDidLayoutSubviews() {
2    super.viewDidLayoutSubviews()
3
4    guard let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
5        return
6    }
7
8    let columns: CGFloat = view.bounds.width > view.bounds.height ? 4 : 2
9    let spacing: CGFloat = 10
10    let totalSpacing = spacing * (columns - 1)
11    let width = (collectionView.bounds.width - totalSpacing) / columns
12
13    layout.itemSize = CGSize(width: width, height: width)
14}

This approach is often simpler than trying to keep separate cached sizes for portrait and landscape manually.

Consider Automatic Invalidation in Custom Layouts

If you use a custom layout subclass, make rotation support part of the layout itself. A common pattern is to invalidate whenever bounds size changes:

swift
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
    return true
}

That keeps the rotation behavior close to the layout logic instead of spreading it across several controller methods.

Common Pitfalls

The biggest mistake is calling reloadData() and expecting the layout to fix itself. Reloading data refreshes cell content, but it does not replace proper layout invalidation.

Another common issue is calculating sizes too early, before the collection view has its final rotated bounds. That leaves the layout using pre-rotation measurements.

People also hardcode orientation-specific sizes instead of deriving them from the actual current width. That becomes fragile on iPad, split view, and other size changes that are not simple portrait-versus-landscape flips.

Finally, custom layouts need the same principle. If you subclass UICollectionViewLayout, invalidate cached attributes whenever bounds changes require new geometry.

Testing on iPad and split-screen sizes is useful too, because those cases often expose assumptions that were hidden on a single full-screen phone layout.

Summary

  • Invalidate the collection view layout when rotation changes the available size.
  • Recompute item sizes from the current collection view bounds.
  • Use viewWillTransition(to:with:) and viewDidLayoutSubviews() appropriately.
  • Do not rely on reloadData() as a substitute for layout invalidation.
  • Derive sizes from actual width instead of hardcoded orientation assumptions.

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.