在不同的设备取向改变UICollectionViewCell大小(Change UICollecti

2019-07-04 02:38发布

我使用的是UICollectionViewUICollectionViewFlowLayout

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

collectionView:layout:sizeForItemAtIndexPath:

当从纵向到横向的切换,我想调整每个单元的尺寸,以完全贴合的CollectionView的大小,不留细胞之间的填充空间。

问题:

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

2)而且,甚至更好,如何让布局,其中的细胞始终适应屏幕的整体尺寸?

Answer 1:

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:将布局失效,并与动画调整细胞(你可以通过零到两个块PARAMS如果你已经没有多余的调整来执行)。

2)代替硬编码的商品尺寸的-collectionView:layout:sizeForItemAtIndexPath ,只是要适应在屏幕上的细胞数除以身高或的CollectionView边界的宽度。 使用高度,如果你的CollectionView水平滚动还是宽度,如果它垂直滚动。



Answer 2:

如果你不想被带来额外的动画performBatchUpdates:completion: ,只要使用invalidateLayout迫使collectionViewLayout重新加载。

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


Answer 3:

我解决了使用两个UICollectionViewFlowLayout。 一个竖拍,一个用于景观。 我把它们dinamically分配给我的CollectionView在-viewDidLoad

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


Answer 4:

有一个简单的方法来设置集合视图单元尺寸:

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

不知道它的动画虽然。



Answer 5:

斯威夫特:收集查看电池是屏幕高度的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)
}


Answer 6:

如果您使用的autolayout 。你只需要invalidate layout旋转和调整时,在您的视图控制器offset在流式布局的子类。

因此,在您的视图控制器 -

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

而在你FlowLayout Subclass

override func prepareLayout() {
    if self.collectionView!.indexPathsForVisibleItems().count > 0{
    var currentIndex : CGFloat!
    currentIndex = CGFloat((self.collectionView!.indexPathsForVisibleItems()[0] as! NSIndexPath).row)
    if let currentVal = currentIndex{
        self.collectionView!.contentOffset = CGPointMake(currentIndex * self.collectionView!.frame.width, self.collectionView!.contentOffset.y);
    }   
    }     
}


文章来源: Change UICollectionViewCell size on different device orientations