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

我正在使用UICollectionViewUICollectionViewFlowLayout

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

 collectionView:layout:sizeForItemAtIndexPath: 

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

问题:

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

2)甚至更好,如何使单元格始终适合屏幕的整个大小的布局?

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

 - (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:将使布局无效,并使用animation调整单元格的大小(如果没有额外的调整,只需将nil传递给两个块参数)。

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

如果您不希望performBatchUpdates:completion:带来的额外animation,只需使用invalidateLayout来强制collectionViewLayout重新加载。

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

我解决了使用两个UICollectionViewFlowLayout。 一个是肖像,一个是风景。 我把它们分配给我的collectionView dinamically在-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]; } } 

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

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

不知道它是否具有animation效果。

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

我需要的是一个单元格是一定百分比的视图高度,并将调整设备的旋转。

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

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

如果您正在使用autolayout invalidate layout ,只需要在旋转视图控制器时invalidate layout视图控制器中的invalidate layout ,并调整stream布局子类中的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); } } }