【问题标题】:UICollectionViewFlowLayout: collectionView!.contentSize vs collectionViewContentSizeUICollectionViewFlowLayout:collectionView!.contentSize 与 collectionViewContentSize
【发布时间】:2015-04-28 10:25:45
【问题描述】:

更新

使用指定的collectionViewContentSize() 方法时,问题似乎已解决,如下所示:

let contentSize = collectionViewContentSize()

尽管如此,我对这种行为背后的解释非常感兴趣,因此我已经相应地更新了我的问题。

原始问题

我正在尝试重新创建this article 的第一个示例中的步骤,但使用的是 Swift 和 Storyboard。

我有一个自定义的UICollectionViewFlowLayout 子类,其内容如下: 导入 UIKit

class SpringyFlowLayout: UICollectionViewFlowLayout {
    
    private lazy var animator: UIDynamicAnimator = {
        return UIDynamicAnimator(collectionViewLayout: self)
        }()
    
    override func prepareLayout() {
        super.prepareLayout()
        
        let contentSize = collectionView!.contentSize
        let items = super.layoutAttributesForElementsInRect(CGRect(origin: CGPointZero, size: contentSize)) as! [UICollectionViewLayoutAttributes]
        
        if animator.behaviors.isEmpty {
            for item in items {
                let spring = UIAttachmentBehavior(item: item, attachedToAnchor: item.center)
                spring.length = 0
                spring.damping = 0.8
                spring.frequency = 1.0
                animator.addBehavior(spring)
            }
        }
    }
    
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
        return animator.itemsInRect(rect)
    }
    
    
    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
        return animator.layoutAttributesForCellAtIndexPath(indexPath)
    }
    
    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
        let delta = newBounds.origin.y - collectionView!.bounds.origin.y
        for spring in animator.behaviors {
            let items = spring.items as! [UICollectionViewLayoutAttributes]
            if let attributes = items.first {
                attributes.center.y += delta
                animator.updateItemUsingCurrentState(attributes)
            }
        }
        return false
    }

我在 Storyboards 中设置了正确的 Layout 类。当我运行应用程序时,我的 Collection View 是空的。

我已确定问题出在以下片段中:

override func prepareLayout() {
        super.prepareLayout()
        
        let contentSize = collectionView!.contentSize
        let items = super.layoutAttributesForElementsInRect(CGRect(origin: CGPointZero, size: contentSize)) as! [UICollectionViewLayoutAttributes]
//...
}

由于我继承了UICollectionViewFlowLayout,我想我可以依靠超级实现为我布置元素,然后修改它们的属性。但是当我检查 contentSize 时,它​​会正确报告宽度,但高度是 0。

这会导致一个空的 items 数组 -> animator 中没有任何行为 -> animator.itemsInRect(_) 返回一个空数组 -> 空的 Collection View。

我似乎无法找出我错过了什么。应该不需要重写contentSize() 方法,因为我使用的是流布局。

【问题讨论】:

    标签: ios swift uicollectionview uicollectionviewlayout uikit-dynamics


    【解决方案1】:

    collectionView 还没有内容大小的问题,因为它刚刚开始准备布局。我不相信调用collectionView!.contentSize 实际上会计算大小。 collectionViewContentSize() 起作用的原因是它会使用您的其他布局代码计算大小。

    【讨论】:

    • 好吧,如果我理解正确的话,调用 super 的 prepareLayout() 实现应该负责布局集合视图(因为它是一个简单的流布局),所以我的 collectionView 应该已经知道它的内容大小(collectionView!.contentSize 确实只返回这个值)。这就是为什么这种情况如此混乱。
    • 我不这么认为。看起来prepareLayout() 没有完成整个布局。它只是在调用更重要的方法之前做任何准备工作。
    • 如果不覆盖collectionViewContentSize()方法,默认实现会查询你的collection view的contentSize属性(继承自UIScrollView。所以感觉我也在用这个属性在引擎盖下,但由于某种原因它在第一次尝试时不正确..
    • 你在哪里发现collectionViewContentSize()使用collectionView.contentSize
    【解决方案2】:

    这里有一些你可能会觉得有趣的东西。我注意到在Ash Furrow 的example in viewDidAppear 中调用了collectionViewLayout.invalidateLayout。 Ash 指出,在使用情节提要时,这不是必需的,因为第一次调用 prepareLayout 的时间与不使用情节提要时的时间不同。

    我尝试使 viewDidAppear 中的集合视图布局以及您的代码和情节提要无效。这是我发现的:

    测试场景:

    1) collectionView!.contentSize without invalidateLayout = cv is EMPTY

    2) collectionViewContentSize() 没有 invalidateLayout = cv WORKS

    3) collectionView!.contentSize with invalidateLayout = cv WORKS

    4) collectionViewContentSize() with invalidateLayout = cv WORKS

    仅供参考

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 2014-10-19
      • 2014-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多