在旋转时调整UICollectionViewCell的大小

时间:2014-10-28 14:53:21

标签: ios rotation uicollectionview

我有一个UICollectionView可以占据整个屏幕。 UICollectionView的单元格与UICollectionView本身一样大,我使用分页。

在旋转设备时,我希望单元格将其大小调整为新的UICollectionView大小。我目前通过在willAnimateRotationToInterfaceOrientation:

中交换布局对象来实现这一目标
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [_collectionView setCollectionViewLayout:[self collectionViewFlowLayoutForOrientation:toInterfaceOrientation] animated:YES];
}

collectionViewFlowLayoutForOrientation:如下:

- (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;
}

它不能按预期工作。

首先,我在控制台中收到一条消息,表明我可能正在做一些不完全合法的事情:

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.  

这是一个公平的信息,当开始动画旋转时,屏幕/ UICollectionView仍然具有旧方向的框架。我倾向于遵守它。

其次,contentOffset在轮换后不正确,因为它没有重新计算。

我已经看到其他解决方案只会使willRotateToInterfaceOrientation:duration:中的布局无效,但这也不会重新计算contentOffset。我通过更改contentOffsetcontentSize进行了跟进,但结果并不完美:

- (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];
}

所以,我的问题是:什么解决方案能够提供预期的结果?

1 个答案:

答案 0 :(得分:0)

尝试添加该行     在设置布局之前[_collectionView invalidateIntrinsicContentSize]。这应该使它重新计算布局,并希望摆脱你的警告信息。