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?

+3


source to share


1 answer


Try adding the line [_collectionView invalidateIntrinsicContentSize] before adjusting the layout. This should recalculate the layout and hopefully get rid of your warning message.



0


source







All Articles