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

时间:2012-11-25 23:09:06

标签: ios uicollectionview uicollectionviewcell

我正在使用UICollectionView UICollectionViewFlowLayout

我通过

设置每个单元格的大小
collectionView:layout:sizeForItemAtIndexPath:

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

问题:

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

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

5 个答案:

答案 0 :(得分: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];
}

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

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

答案 1 :(得分:33)

如果您不想要performBatchUpdates:completion:带来的其他动画,只需使用invalidateLayout强制collectViewLayout重新加载。

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
}

答案 2 :(得分: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];
}

然后我简单地修改了我的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;
}

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

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

答案 3 :(得分:8)

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

UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);

不确定它是否可以动画。

答案 4 :(得分: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)
}