UICollectionView使边界更改上的布局无效
我目前有以下片段用于计算UICollectionViewCells
大小:
- (CGSize)collectionView:(UICollectionView *)mainCollectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)atIndexPath { CGSize bounds = mainCollectionView.bounds.size; bounds.height /= 4; bounds.width /= 4; return bounds; }
这很有效。 但是,我现在在viewDidLoad
添加了一个键盘观察器(它在UICollectionView
出现之前触发了它的委托和数据源方法,并从故事板中调整自身大小)。 因此,界限是错误的。 我也想支持轮换。 如果UICollectionView
改变大小,处理这两个边缘情况并重新计算大小的好方法是什么?
当集合视图的边界发生变化时,使布局无效的解决方案是覆盖shouldInvalidateLayoutForBoundsChange:
并返回YES
。 它也在文档中说明: https : //developer.apple.com/documentation/uikit/uicollectionviewlayout/1617781-shouldinvalidatelayoutforboundsc
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; }
这也应该包括旋转支持。 如果没有,请实现viewWillTransitionToSize:withTransitionCoordinator:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [coordinator animateAlongsideTransition:^(id context) { [self.collectionView.collectionViewLayout invalidateLayout]; } completion:^(id context) { }]; }
-
您应该在更改集合视图大小时处理该情况。 如果更改方向或约束,将触发viewWillLayoutSubviews方法。
-
您应该使当前集合视图布局无效。 使用invalidateLayout方法使布局无效后,将触发UICollectionViewDelegateFlowLayout方法。
这是示例代码:
- (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [mainCollectionView.collectionViewLayout invalidateLayout]; }
这种方法允许你在没有子类化布局的情况下完成它,而是将它添加到你的,可能已经存在的UICollectionViewController
子类,并避免递归调用viewWillLayoutSubviews
的可能性,它是接受的解决方案的变体,稍微简化,因为它不使用transitionCoordinator
。 在Swift中:
override func viewWillTransition( to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator ) { super.viewWillTransition(to: size, with: coordinator) collectionViewLayout.invalidateLayout() }