当边界 UICollectionView 更改时调整单元格大小

Posted

技术标签:

【中文标题】当边界 UICollectionView 更改时调整单元格大小【英文标题】:Resize cells when bounds UICollectionView change 【发布时间】:2014-02-10 17:01:14 【问题描述】:

我正在使用水平分页UICollectionView 来显示可变数量的集合视图单元格。每个集合视图单元格的大小需要等于集合视图的大小,并且每当集合视图的大小发生变化时,集合视图单元格的大小都需要相应更新。后者正在引起问题。当集合视图的大小发生变化时,集合视图单元格的大小不会更新。

使布局无效似乎并不能解决问题。继承 UICollectionViewFlowLayout 并覆盖 shouldInvalidateLayoutForBoundsChange: 也不起作用。

为了您的信息,我使用UICollectionViewFlowLayout 的实例作为集合视图的布局对象。

【问题讨论】:

我也有类似的问题。你修好吗?谢谢 @damacri86 我通过子类化UIScrollView 创建了一个自定义集合视图。这让我可以更好地控制集合视图的行为,这正是我在这个项目中所需要的。 【参考方案1】:

我认为下面的解决方案更清洁。您只需要覆盖 UICollectionViewLayout 的方法之一,例如:

- (void)invalidateLayoutWithContext:(UICollectionViewFlowLayoutInvalidationContext *)context

  context.invalidateFlowLayoutAttributes = YES;
  context.invalidateFlowLayoutDelegateMetrics = YES;
  [super invalidateLayoutWithContext:context];

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

  if(!CGSizeEqualToSize(self.collectionView.bounds.size, newBounds.size))
  
    return YES;
  

  return NO;

也是。

【讨论】:

【参考方案2】:

我的应用程序中有类似的行为:UICollectionView 的单元格应始终与集合视图具有相同的宽度。只是从shouldInvalidateLayoutForBoundsChange: 返回true 对我也不起作用,但我设法使它以这种方式工作:

class AdaptableFlowLayout: UICollectionViewFlowLayout 
    var previousWidth: CGFloat?

    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool 
        let newWidth = newBounds.width
        let shouldIvalidate = newWidth != self.previousWidth
        if shouldIvalidate 
            collectionView?.collectionViewLayout.invalidateLayout()
        
        self.previousWidth = newWidth
        return false
    

在文档中指出,当shouldInvalidateLayoutForBoundsChange 返回true 时,将调用invalidateLayoutWithContext:。我不知道为什么invalidateLayout 有效而invalidateLayoutWithContext: 无效。

【讨论】:

【参考方案3】:

高度变化的 Swift 4 Xcode 9 实现:

final class AdaptableHeightFlowLayout: UICollectionViewFlowLayout 
    var previousHeight: CGFloat?

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool 
        let newHeight = newBounds.height
        let shouldIvalidate = newHeight != self.previousHeight
        if shouldIvalidate 
            collectionView?.collectionViewLayout.invalidateLayout()
        
        self.previousHeight = newHeight
        return false
    

【讨论】:

以上是关于当边界 UICollectionView 更改时调整单元格大小的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 包装器视图框架更新

在旋转时调整 UICollectionViewCells 的大小会更改当前可见的单元格 [重复]

UICollectionView 的 didSelectItemAt 仅在双击时调用

UICollectionView 的 didSelectItemAtIndexPath 仅在用两根手指选择单元格时调用

为啥我的 UICollectionView 支持方法仅在我的 ViewController 设置为初始视图控制器时调用?

当 UICollectionView 更改布局时覆盖 UIAccessibilityLayoutChangedNotification