How to invalidate flow collection view layout on rotation
Say you want to have grid layout with cells always half the size of the screen’s width. You want to maintain that layout in both portrait and landscape. Since iOS 8 that can’t be easier, with the right incantations.
First, subclass UICollectionViewFlowLayout
.
Then add the following method into it:
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBounds {
UICollectionViewFlowLayoutInvalidationContext *context = (UICollectionViewFlowLayoutInvalidationContext *)[super invalidationContextForBoundsChange:newBounds];
context.invalidateFlowLayoutDelegateMetrics = (
CGRectGetWidth(newBounds) != CGRectGetWidth(self.collectionView.bounds) ||
CGRectGetHeight(newBounds) != CGRectGetHeight(self.collectionView.bounds)
);
return context;
}
The key here is casting returned context from super
as UICollectionViewFlowLayoutInvalidationContext
which allows you to toggle the invalidateFlowLayoutDelegateMetrics
property. That will tell UIKit that it should re-query FlowLayout’s delegate for the sizes.
In the collection view controller, make sure it’s set to adopt UICollectionViewDelegateFlowLayout
protocol and then add this delegate call:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewFlowLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(floor(self.view.bounds.size.width/2.0), 88);
}
Done.