首页 > 解决方案 > 使用缓存的 UICollectionViewLayoutAttributes 子类化 UICollectionViewLayout

问题描述

我正在尝试了解其UICollectionViewLayout工作原理并找到了此示例代码。

https://developer.apple.com/documentation/uikit/uicollectionview/customizing_collection_view_layouts

在示例代码(以及我能找到的所有其他示例)中,它具有cachedLayoutAttributes对象并计算prepare().

我发现此模式有 2 个问题。

一是如果数据源的数量足够大,计算prepare()方法中的所有内容都需要时间(并且每当collectionView的布局发生变化时都会重新计算),因此看起来效率不高。

另一个问题是没有机会layoutAttributesForItemlayoutAttributesForSupplementaryView被叫。仅layoutAttributesForElements被调用,似乎足以布置单元格/补充视图。

我阅读了文档,但它只说必须覆盖这些方法。我最好的猜测是我应该使用覆盖这些方法来返回适当的UICollectionViewLayoutAttributes并从layoutAttributesForElements. 但是layoutAttributesForElements,每当用户滚动 UICollectionView 时都会调用它,因此它似乎也不是很有效。

我想知道是什么情况layoutAttributesForItem并被调用,如果数据源的数量很大layoutAttributesForSupplementaryView,计算的最佳方式/地点/时间是什么/何时/何地。UICollectionViewLayoutAttributes

更新

感谢您的评论。然而,它似乎是关于失效周期的优化。

旨在支持失效上下文的布局对象可以使用 UICollectionViewLayoutInvalidationContext 对象中的信息来优化它们在失效周期期间的行为。

这意味着UICollectionViewLayoutAttributes已经设置并且只有必要的部分无效,对吗?

UICollectionViewLayoutAttributes那么,第一次应该在哪里计算呢?如果我错了,请告诉我。

标签: iosswiftuicollectionviewuicollectionviewlayout

解决方案


一是如果数据源的数量足够大,计算prepare()方法中的所有内容都需要时间(并且每当collectionView的布局发生变化时都会重新计算),因此看起来效率不高。

是的,它看起来效率不高。使prepare()计算尽可能高效是您的工作。

例如:只计算一部分属性,当使用 .scroll 改变它的位置时计算更多shouldInvalidateLayout(forBoundsChange:)。但是要小心这种方法,因为它可能会使每个像素滚动的布局无效。

prepare()调用方法不仅仅是为了好玩,它会通知您某些内容已更改并且需要重新计算!但是很难获得有关变化的信息。您可以在准备之前检查IGListKit如何获取有关更改的信息:链接

另一个问题是没有机会layoutAttributesForItemlayoutAttributesForSupplementaryView被叫。仅layoutAttributesForElements被调用,似乎足以布置单元格/补充视图。

layoutAttributesForElements(in:)首先调用,因为该集合不知道您的单元格和补充视图的顺序。所以它要求指定矩形中的所有属性。尝试插入/移动/删除/重新加载单元格,我相信layoutAttributesForItem(at:)可能会被调用。或者可能不是。但是您不必担心,因为您已经拥有属性缓存。

由于您缓存属性layoutAttributesForElements(in:)应该足够高效,并且看起来像这样:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    return attributes
        .reduce(into: [UICollectionViewLayoutAttributes](), { $0 += $1.filter({ $0.frame.intersects(rect) }) })
}

我个人建议查看一些困难的开源布局。UICollectionViewLayout您将从任何简单的示例项目中获得有关比较信息的更多信息。


推荐阅读