0
votes

My code works fine on iOS 11, but it crashes occasionally on iOS 12. The error I get is:

Assertion failure in -[UICollectionViewData validateLayoutInRect:]. Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: {length = 2, path = 1 - 0}

I have a collection view showing several sections. I reload one of the sections when I get new data from the server. The code I use to reload the section is:

let attributes = calculateAttributesFrom(items)
layout.firstSectionAttributes = attributes                
collectionView.reloadSections([kFirstSectionIndex])

The number of items in a section is:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if indexPath.section == kFirstSectionIndex {
        return layout.firstSectionAttributes.count
    } 
    ...
}

I use layout.firstSectionAttributes.count as the number of items in the sections. This means each attribute must have a corresponding cell. I guess this is related to layout.invalidateLayout(). I tried to add it before and after the reload, but it did not help.

Does anyone have any idea?

Edit

It does not crash anymore after I replace reloadSections with reloadData. But I only want to reload one section instead of all of them.

1
Are you using a custom layout class?user5924595
@MarkusSchmid Yesukim
It would be worth a try to add all invalid item indexes (= indexes of items where the layout has changed or indexes of items that does not exist anymore) to the invalidationContext where let invalidationContext = super.invalidationContext(forBoundsChange: newBounds) in override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext. And take care of override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? and override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool)...user5924595
Hi @mark61, can you explain this approach a bit more. I am not using prepare() method in my custom UICollectionViewFlowLayout class so I don't have cache. I wanted to remove all the existing data and recreate based on the new data provided(reduced number of rows)user121095

1 Answers

-1
votes

Try this:

collectionView.reloadSections(IndexSet(integer: kFirstSectionIndex))