在不同的设备方向上更改UICollectionViewCell大小

Fme*_*ina 99 ios uicollectionview uicollectionviewcell

我使用的是UICollectionViewUICollectionViewFlowLayout.

我通过设置每个单元格的大小

collectionView:layout:sizeForItemAtIndexPath:
Run Code Online (Sandbox Code Playgroud)

当从纵向切换到横向时,我想调整每个单元格的大小以完全适合CollectionView的大小,而不会在单元格之间留下填充空间.

问题:

1)如何在旋转事件后更改单元格的大小?

2)而且,更好的是,如何使单元格总是适合整个屏幕大小的布局?

fol*_*ben 200

1)您可以维护和交换多个布局对象,但有一种更简单的方法.只需将以下内容添加到UICollectionViewController子类中,并根据需要调整大小:

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{    
    // Adjust cell size for orientation
    if (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
        return CGSizeMake(170.f, 170.f);
    }
    return CGSizeMake(192.f, 192.f);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.collectionView performBatchUpdates:nil completion:nil];
}
Run Code Online (Sandbox Code Playgroud)

调用-performBatchUpdates:completion:将使布局无效并使用动画调整单元格的大小(如果您没有执行额外调整,则可以将nil传递给两个块参数).

2)不要将项目大小硬编码-collectionView:layout:sizeForItemAtIndexPath,只需将collectionView的边界的高度或宽度除以您想要适合屏幕的单元格数.如果collectionView水平滚动,则使用高度;如果它垂直滚动,则使用宽度.

  • 在iOS 8中不推荐使用`didRotateFromInterfaceOrientation` (9认同)
  • 在iOS8上,我在`viewWillTransitionToSize`中调用`coordinator.animateAlongsideTransition`,并在其`animation`块中调用`performBatchUpdates`.这给出了一个很好的动画效果. (8认同)
  • @ user102008调用`invalidateLayout`将重新绘制具有正确大小的单元格,但`-performBatchUpdates:completion:`将动画更改,这看起来好多了恕我直言. (7认同)
  • 在我的情况下,代码不会调整collectionviewcell的大小,直到我滚动屏幕. (4认同)
  • 为什么不直接调用`[self.collectionView.collectionViewLayout invalidateLayout];`? (3认同)

Hai*_*Kao 33

如果你不想要带来额外的动画performBatchUpdates:completion:,只需使用invalidateLayout强制collectionViewLayout重新加载.

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
}
Run Code Online (Sandbox Code Playgroud)


Fiv*_*gle 13

我解决了使用两个UICollectionViewFlowLayout.一个用于纵向,一个用于横向.我在-viewDidLoad中将它们分配给我的collectionView

self.portraitLayout = [[UICollectionViewFlowLayout alloc] init];
self.landscapeLayout = [[UICollectionViewFlowLayout alloc] init];

UIInterfaceOrientation orientationOnLunch = [[UIApplication sharedApplication] statusBarOrientation];

if (UIInterfaceOrientationIsPortrait(orientationOnLunch)) {
    [self.menuCollectionView setCollectionViewLayout:self.portraitLayout];
} else {
    [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout];
}
Run Code Online (Sandbox Code Playgroud)

然后我简单地修改了我的collectionViewFlowLayoutDelgate方法

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    CGSize returnSize = CGSizeZero;

    if (collectionViewLayout == self.portraitLayout) {
        returnSize = CGSizeMake(230.0, 120.0);
    } else {
        returnSize = CGSizeMake(315.0, 120.0);
    }

    return returnSize;
}
Run Code Online (Sandbox Code Playgroud)

最后我在旋转时从布局切换到另一个

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
    if (UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) {
        [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout animated:YES];
    } else {
        [self.menuCollectionView setCollectionViewLayout:self.portraitLayout animated:YES];
    }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*e P 8

有一种设置集合视图单元大小的简单方法:

UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);
Run Code Online (Sandbox Code Playgroud)

不确定它是否可以动画.


Dog*_*fee 7

Swift:集合视图单元格,是屏幕高度的n%

我需要的是一个视图高度的特定百分比的单元格,并且会随着设备旋转而调整大小.

在上面的帮助下,这是解决方案

override func viewDidLoad() {
    super.viewDidLoad()
    automaticallyAdjustsScrollViewInsets = false
    // if inside nav controller set to true
}

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    collectionViewLayout.invalidateLayout()
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSize(width: 100, height: collectionView.frame.height * 0.9)
}
Run Code Online (Sandbox Code Playgroud)