Justin Duke

Avoiding UICollectionViewController crashes when reloading data

This honestly is less of a post and more of a public service announcement, because as I was migrating a bunch of UITableViews in Barback to UICollectionViews I ran into an apparently obscure problem:

  1. The backing data store of the UICollectionView (let’s call it items: [String]) changes.
  2. When that happens, we want to call self.collectionView.reloadData to update the collection view.
  3. Naturally, the app then crashes with UICollectionView received layout attributes for a cell with an index path that does not exist
  4. Wait, what?

Yeah, I ran into this and it was surprisingly difficult to find an answer for, given that it seems like such a basic problem!

The answer is simple, to change this:

var items: [String] = [] {
    didSet {
        self.collectionView?.reloadData()
    }
}

To this:

var items: [String] = [] {
    didSet {
        self.collectionView?.reloadData()
        self.collectionViewLayout.invalidateLayout()
    }
}

That’s literally all you have to do: let the collection view’s layout object know that it’s not valid any more, since the data that the layout is based off of is no longer valid.

(I hope this helps, and saves you a couple minutes of research!)

Liked this post? You should subscribe to my newsletter and follow me on Twitter.

(I've got an RSS feed, too, if you'd prefer.)