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

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

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

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

【问题讨论】:

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

标签: uicollectionview uicollectionviewcell


【解决方案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
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多