Crash using UICollectionView and custom flow layout

I have implemented sticky section headers for the collection view using http://blog.radi.ws/post/32905838158/sticky-headers-for-uicollectionview-using as a jump point and they work.

But I see a very strange crash.

When I click on the detail view of the editor, change the item name so that it moves from one section to another (think changing the last name of the person in the contact list, which is grouped by the first letter of the last name) and then pops up back to the collection view, it crashes with a complaint

UICollectionView received layout attributes for a cell with an index path that does not exist

      

Here's the flow of execution:

In the detailed view of the editor, I change the element name so that it goes from section X to section Y.

The element model emits a name change notification.

The root view controller that owns the collection view catches the "name changed" notification, rebuilds its internal indexes, and then calls -reloadData on the collection view. It's all good.

I click the back button in the UI and the following thread happens (confirmed via NSlog debugger and bugger calls)

  • numberOfSectionsInCollectionView: is called and my code is returning the correct number of sections
  • collectionView: numberOfItemsInSection: is called for each section and the correct number of items is returned.
  • My custom thread layout -layoutAttributesForElementsInRect: is being called. The first thing I do there is call [super layoutAttributesForElementsInRect] to get the basic layout.

Entry in Inherited Source Layout I see the attributes for the previous cell layout, not the current one. For example, the layout for layout before editing that I just did. So, wrong sections and or cells in wrong sections.

Now that's what's in my head.

If I comment out the whole implementation of -layoutAttributesForElementsInRect it still crashes. But, if I comment:

- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBound {
    return YES;
}

      

Then it works correctly.

This tells me that the collection view or something in the stream layout is results caching, but only if the stream layout should InvalidateLayoutForBoundsChange

Please note, if I just use vanilla UICollectionViewFlowLayout everything works fine.

TL; DR

Custom UICollectionViewFlowLayout, if -shouldInvalidateLayoutForBoundsChange returns YES, gets deprecated layout attributes from [super layoutAttributesForElementsInRect]

Any ideas?

+3


source to share


1 answer


I solved this by removing the override shouldInvalidateLayoutForBoundsChange:

and instead doing it scrollViewDidScroll:

in the collection view delegate to invalidate the layout:

override func scrollViewDidScroll(scrollView: UIScrollView) {
    collectionView?.collectionViewLayout.invalidateLayout()
}

      



This keeps sticky headers but stops crashing.

0


source







All Articles