我使用的是UICollectionView
与UICollectionViewFlowLayout
。
我通过设置每个单元格的大小
collectionView:layout:sizeForItemAtIndexPath:
当从纵向到横向的切换,我想调整每个单元的尺寸,以完全贴合的CollectionView的大小,不留细胞之间的填充空间。
问题:
1)旋转事件之后如何更改单元格的大小?
2)而且,甚至更好,如何让布局,其中的细胞始终适应屏幕的整体尺寸?
我使用的是UICollectionView
与UICollectionViewFlowLayout
。
我通过设置每个单元格的大小
collectionView:layout:sizeForItemAtIndexPath:
当从纵向到横向的切换,我想调整每个单元的尺寸,以完全贴合的CollectionView的大小,不留细胞之间的填充空间。
问题:
1)旋转事件之后如何更改单元格的大小?
2)而且,甚至更好,如何让布局,其中的细胞始终适应屏幕的整体尺寸?
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水平滚动还是宽度,如果它垂直滚动。
如果你不想被带来额外的动画performBatchUpdates:completion:
,只要使用invalidateLayout
迫使collectionViewLayout重新加载。
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.collectionView.collectionViewLayout invalidateLayout];
}
我解决了使用两个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];
}
}
有一个简单的方法来设置集合视图单元尺寸:
UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);
不知道它的动画虽然。
斯威夫特:收集查看电池是屏幕高度的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)
}
如果您使用的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);
}
}
}