【问题标题】:Behavior of UICollectionViewLayout.layoutAttributesForElementsInRectUICollectionViewLayout.layoutAttributesForElementsInRect 的行为
【发布时间】:2020-04-08 23:16:10
【问题描述】:

我已经实现了我自己的集合视图布局,它是 UICollectionViewLayout 的子类。在prepare 中,我计算并缓存布局属性。 在layoutAttributesForElementsInRect 中,我过滤掉那些超出矩形的:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    return itemAttributesCache.filter { $0.frame.intersects(rect) }
}

我希望为layoutAttributesForElementsInRect中返回的每个索引路径调用数据源方法func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

但是我发现如果我只返回这样的整个属性集:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    return itemAttributesCache
}

cellForItemAt 方法仍然只为可见矩形内的属性调用。

这是预期的行为吗?如果是的话,在我的代码中过滤属性的目的是什么,如果集合视图本身可以做到这一点?我没有发现任何性能问题。

是否可以强制collectionview为所有返回的属性调用cellForItemAt

【问题讨论】:

  • 如果你还没有看过这个 WWDC 演讲,我强烈推荐它,他们在这里解释了很多你不清楚的地方。 developer.apple.com/videos/play/wwdc2018/225
  • @OscarApeland 在那次谈话中没有回答我的问题

标签: ios objective-c swift uicollectionview uicollectionviewlayout


【解决方案1】:

是的,这是集合视图的预期行为。在UICollectionViewLayout Apple 的文档中说(强调):

布局对象的工作是确定单元格、补充视图和装饰视图的位置在集合视图的范围内,并在被询问时将该信息报告给集合视图。

然后继续:

集合视图在许多不同的时间要求它的布局对象为这些元素提供布局信息。 屏幕上显示的每个单元格和视图都使用来自布局对象的信息进行定位。

代码中过滤属性的目的是提高性能。影响布局对象性能的主要有三个因素:

  • 集合视图数据源中的项目数。
  • 确定布局属性的复杂性。
  • 自定义布局属性所需的内存量。

在上述条件不友好的情况下(你有很多物品,计算属性很复杂,你的自定义属性需要大量内存)提前计算所有属性是不可行的因为预先计算这些值会花费大量时间和资源,因此您不必在prepare 函数中缓存它们,而是必须在layoutAttributesForElementsInRect 中实现一些逻辑来计算布局属性。在这种情况下,您可以使用 visible rect 参数仅计算将在屏幕上可见的单元格和视图的属性值。

关于强制集合视图为所有返回的属性调用cellForItemAt,我不确定这样做的价值是什么,因为它只会使用其中的几个。实现这一目标的唯一方法是拥有一个与您正在显示的内容大小相同的集合视图,以便所有单元格都被视为可见。但是,这样做首先会使使用集合视图的意义无效,因为单元格不会被重用,也不会滚动。如果您尝试使用集合视图项修复一些奇怪的动画,这不是要走的路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 2011-08-31
    • 2012-11-08
    • 2015-09-14
    • 2011-09-15
    • 2013-04-05
    相关资源
    最近更新 更多