旋转时调整 UICollectionViewCell 的大小

3
我有一个占据整个屏幕的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];
}

所以,我的问题是:什么解决方案可以达到预期的结果?

你正在使用哪个iOS SDK来构建你的应用程序? - rahulinaction
我知道在iOS8上willRotateToInterfaceOrientation:duration:已经被弃用,但是目前我仍然支持iOS7。 - MrJre
你找到解决方案了吗? - Daniel Galasko
你找到解决方案了吗? - Just a coder
不,我还没有。最终我认为我放弃了这种方法。 - MrJre
1个回答

0
尝试在设置布局之前添加以下行: [_collectionView invalidateIntrinsicContentSize] 这应该会导致重新计算布局,并希望消除警告消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接