Resizing UICollectionViewCell on rotation
I have a UICollectionView that displays the entire screen. UICollectionView
has cells the size of UICollectionView
and I am using paging.
When I rotate the device, I want the cells to adjust their size to the new size UICollectionView
. I am currently achieving this by replacing the layout object in willAnimateRotationToInterfaceOrientation:
:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[_collectionView setCollectionViewLayout:[self collectionViewFlowLayoutForOrientation:toInterfaceOrientation] animated:YES];
}
c collectionViewFlowLayoutForOrientation:
looks like this:
- (UICollectionViewFlowLayout *)collectionViewFlowLayoutForOrientation:(UIInterfaceOrientation)orientation
{
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
CGFloat width = UIInterfaceOrientationIsLandscape(orientation) ? MAX(screenSize.width, screenSize.height) : MIN(screenSize.width, screenSize.height);
CGFloat height = UIInterfaceOrientationIsLandscape(orientation) ? MIN(screenSize.width, screenSize.height) : MAX(screenSize.width, screenSize.height);
UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[collectionViewFlowLayout setItemSize:CGSizeMake(width, height)];
[collectionViewFlowLayout setMinimumLineSpacing:0.0f];
[collectionViewFlowLayout setSectionInset:UIEdgeInsetsZero];
[collectionViewFlowLayout setMinimumInteritemSpacing:0.0f];
return collectionViewFlowLayout;
}
It doesn't work as expected.
First of all, I get a message in the console indicating that I am probably doing something not entirely legal:
the behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less than the height of the UICollectionView minus the section insets top and bottom values.
This is a fair post, since the animation starts to rotate, the screen / UICollectionView
still has a border for the old orientation. I would be inclined to observe this.
Second, it is contentOffset
incorrect after rotation, since it does not get recalculated.
I have seen other solutions that are simply not valid for layout in willRotateToInterfaceOrientation:duration:
, but that doesn't recalculate contentOffset
. I followed it, changing contentOffset
and contentSize
as follows, but the result is not perfect either:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
CGSize fromCollectionViewSize = [self collectionViewSizeForOrientation:[self interfaceOrientation]];
CGSize toCollectionViewSize = [self collectionViewSizeForOrientation:toInterfaceOrientation];
CGFloat currentPage = [_collectionView contentOffset].x / [_collectionView bounds].size.width;
NSInteger itemCount = [_collectionView numberOfItemsInSection:0];
UICollectionViewFlowLayoutInvalidationContext *invalidationContext = [[UICollectionViewFlowLayoutInvalidationContext alloc] init];
[invalidationContext setContentSizeAdjustment:CGSizeMake((toCollectionViewSize.width - fromCollectionViewSize.width) * itemCount, toCollectionViewSize.height - fromCollectionViewSize.height)];
[invalidationContext setContentOffsetAdjustment:CGPointMake(currentPage * toCollectionViewSize.width - [_collectionView contentOffset].x, 0)];
[[_collectionView collectionViewLayout] invalidateLayoutWithContext:invalidationContext];
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
So my question is: What solution gives the intended result?
source to share