UICollectionView使边界更改上的布局无效

Stu*_*ssa 23 objective-c ios

我目前有以下用于计算UICollectionViewCells大小的代码段:

- (CGSize)collectionView:(UICollectionView *)mainCollectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)atIndexPath
{
    CGSize bounds = mainCollectionView.bounds.size;
    bounds.height /= 4;
    bounds.width /= 4;
    return bounds;
}
Run Code Online (Sandbox Code Playgroud)

这有效.但是,我现在正在添加一个键盘观察器viewDidLoad(它触发了UICollectionView它出现之前的委托和数据源方法,并从故事板中调整自身大小).因此,界限是错误的.我也想支持轮换.如果UICollectionView更改大小,处理这两个边缘情况并重新计算尺寸的好方法是什么?

tub*_*tub 48

当集合视图的边界发生更改时,使布局无效的解决方案是覆盖shouldInvalidateLayoutForBoundsChange:并返回YES.它也在文档中说明:https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617781-shouldinvalidatelayoutforboundsc

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds 
{
     return YES;
}
Run Code Online (Sandbox Code Playgroud)

这也应该包括旋转支持.如果没有,请执行viewWillTransitionToSize:withTransitionCoordinator:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size
          withTransitionCoordinator:coordinator];

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
         [self.collectionView.collectionViewLayout invalidateLayout];
     }
                                 completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
     }];
}
Run Code Online (Sandbox Code Playgroud)

  • `shouldInvalidateLayoutForBoundsChange`听起来不错,但对我不起作用。手动调用`invalidateLayout`即可!谢谢! (3认同)

eXt*_*eme 10

  1. 您应该在更改集合视图大小时处理该情况.如果更改方向或约束,将触发viewWillLayoutSubviews方法.

  2. 您应该使当前集合视图布局无效.使用invalidateLayout方法使布局无效后,将触发UICollectionViewDelegateFlowLayout方法.

这是示例代码:

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

  • 当我尝试这个时,我的应用程序挂起,因为`-viewWillLayoutSubviews`方法被无限调用..我把那个代码放到了错误的控制器中吗?我也可以调用超级? (15认同)