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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13556554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:19:23  来源:igfitidea点击:

Change UICollectionViewCell size on different device orientations

iosuicollectionviewuicollectionviewcell

提问by Fmessina

I am using an UICollectionViewwith UICollectionViewFlowLayout.

我正在使用UICollectionViewwith UICollectionViewFlowLayout

I set the size of each cell through the

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

collectionView:layout:sizeForItemAtIndexPath:

When switching from portrait to landscape, I would like to adjust the size of each cell to completely fit the size of the CollectionView, without leaving padding space between cells.

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

Questions:

问题:

1) How to change the size of a cell after a rotation event?

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

2) And, even better, how to make the layout where the cells always fit the entire size of the screen?

2)而且,更好的是,如何使单元格始终适合整个屏幕尺寸的布局?

回答by followben

1) You could maintain and swap out multiple layout objects, but there's a simpler way. Just add the following to your UICollectionViewControllersubclass and adjust the sizes as required:

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

Calling -performBatchUpdates:completion:will invalidate the layout and resize the cells with animation (you can just pass nil to both block params if you've no extra adjustments to perform).

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

2) Instead of hardcoding the item sizes in -collectionView:layout:sizeForItemAtIndexPath, just divide the height or width of the collectionView's bounds by the number of cells you want to fit on screen. Use the height if your collectionView scrolls horizontally or the width if it scrolls vertically.

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

回答by Hai Feng Kao

If you don't want additional animations brought by performBatchUpdates:completion:, just use invalidateLayoutto force the collectionViewLayout to reload.

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

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

回答by Fiveagle

I solved using two UICollectionViewFlowLayout. One for portrait and one for landscape. I assign them to my collectionView dinamically in -viewDidLoad

我使用两个 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];
}

Then I simply modified my collectionViewFlowLayoutDelgate Methods like this

然后我只是像这样修改了我的 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;
}

Last I switch from a layout to one other on rotation

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

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

回答by Dannie P

There's a simple way to set collection view cell size:

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

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

Not sure if it's animatable though.

不确定它是否可以动画化。

回答by DogCoffee

Swift : Collection View Cell that is n% of screen height

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

I needed was a cell that was a certain percentage of views height, and would resize with device rotation.

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

With help from above, here is the solution

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

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)
}

回答by toofani

If you are using autolayout.You just need to invalidate layoutin your view controller when rotating and adjust offsetin your flow layout subclass.

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

So, In your view controller -

所以,在你的视图控制器中 -

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

And in your FlowLayout Subclass

而在你 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);
    }   
    }     
}