CollectionView
sizeForItemAtIndexPath
iOS development
UICollectionView
debugging

CollectionView sizeForItemAtIndexPath never called

Master System Design with Codemia

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

Introduction

If collectionView(_:layout:sizeForItemAt:) is never called, the problem is usually configuration, not the method body. That delegate method belongs to UICollectionViewDelegateFlowLayout, so it is only used when the collection view is actually running with a flow layout and a working delegate. The fastest way to debug it is to verify layout type, delegate assignment, and the method signature in that order.

Make Sure the Layout Is a Flow Layout

The method is part of the flow-layout delegate path. If your collection view uses a compositional layout or some other custom layout, sizeForItemAt is not the sizing mechanism.

swift
1if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
2    layout.minimumInteritemSpacing = 8
3    layout.minimumLineSpacing = 8
4}

If the cast fails, that explains why the method is not called.

A typical setup looks like this:

swift
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
collectionView.collectionViewLayout = layout

Without a flow layout, flow-layout delegate sizing does not apply.

Conform to UICollectionViewDelegateFlowLayout

Your controller or delegate object must adopt UICollectionViewDelegateFlowLayout, not only UICollectionViewDelegate.

swift
1final class ViewController: UIViewController,
2                            UICollectionViewDataSource,
3                            UICollectionViewDelegateFlowLayout {
4
5    @IBOutlet private weak var collectionView: UICollectionView!
6
7    func collectionView(_ collectionView: UICollectionView,
8                        layout collectionViewLayout: UICollectionViewLayout,
9                        sizeForItemAt indexPath: IndexPath) -> CGSize {
10        return CGSize(width: 120, height: 80)
11    }
12}

The signature must match exactly. If the method name or parameter labels are slightly wrong, Swift compiles a different method and the collection view never calls it.

Verify the Delegate Is Set

Even with the right protocol, the method will not run if the collection view's delegate is nil or points to a different object.

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    collectionView.delegate = self
4    collectionView.dataSource = self
5}

If you use Interface Builder, check the connection there too. A broken outlet or stale storyboard connection is a common reason the method appears to be ignored.

Self-Sizing and Estimated Item Size

Another important case is self-sizing cells. If you enable estimatedItemSize, Auto Layout may drive sizing instead of sizeForItemAt.

swift
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    layout.estimatedItemSize = .zero
}

If you want sizeForItemAt to decide item sizes, disable self-sizing behavior that would otherwise take over.

Reload and Invalidate When Needed

If the delegate method was not called during the initial layout pass, changing layout-related state later may require invalidating the layout.

swift
collectionView.collectionViewLayout.invalidateLayout()
collectionView.reloadData()

This does not fix missing delegate wiring, but it helps when the method works only intermittently after size changes or dynamic content updates.

Storyboard and Interface Builder Checks

If the collection view was created in Interface Builder, verify that the view controller class in the storyboard is the same class that implements the delegate method. It is easy to update code, forget the storyboard class assignment, and then spend time debugging a method that is never reachable from the actual runtime object.

Also check whether another object was accidentally connected as the delegate. The method can be implemented perfectly and still never run if the storyboard wiring points somewhere else.

Common Pitfalls

The most common mistake is using a non-flow layout and expecting a flow-layout delegate method to run.

Another issue is forgetting to adopt UICollectionViewDelegateFlowLayout or using the wrong Swift method signature.

Developers also often overlook the delegate connection. If the collection view's delegate is not the object implementing the method, the method will never fire.

Finally, self-sizing cells can make it look as if sizeForItemAt is broken when Auto Layout sizing is actually taking precedence.

Summary

  • 'sizeForItemAt is used only with UICollectionViewFlowLayout and a valid flow-layout delegate.'
  • Make sure the delegate object conforms to UICollectionViewDelegateFlowLayout.
  • Verify the delegate and data source are connected to the right object.
  • Check the exact Swift method signature.
  • Disable self-sizing or invalidate the layout if another sizing path is overriding the delegate method.

Course illustration
Course illustration

All Rights Reserved.