UICollectionViewLayout.layoutAttributesForElementsInRect的行为

问题描述 投票:-1回答:1

我已经实现了我自己的从UICollectionViewLayout继承的集合视图布局。在prepare中,我计算并缓存布局属性。在layoutAttributesForElementsInRect中,我过滤掉不正确的内容:

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

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

但是我发现是否只返回那样的整个属性集:

layoutAttributesForElementsInRect

[override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return itemAttributesCache } 方法仍仅对可见矩形内的属性调用。

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

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

ios objective-c swift uicollectionview uicollectionviewlayout
1个回答
0
投票

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

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

然后继续:

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

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

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

在上述条件不友好的情况下(您有很多项目,计算属性非常复杂,而您的自定义属性需要大量内存),事先计算所有属性是不可行的,因为预计算这些值将花费大量时间和资源,因此,与其在UICollectionViewLayout函数中进行缓存,还不如在UICollectionViewLayout中实现一些逻辑以计算布局属性。在这种情况下,您可以使用可见矩形参数来仅计算将在屏幕上可见的单元格和视图的属性值。

关于强制集合视图为所有返回的属性调用prepare,我不确定这样做的意义是什么,因为它将仅使用其中的几个。实现此目的的唯一方法是使用集合视图查看所显示内容的大小,以便将所有单元格都视为可见。但是,这样做将使使用集合视图的初衷无效,因为不会重复使用单元格并且它不会滚动。如果您要使用收藏夹视图项来修复一些怪异的动画,那是不可行的。

© www.soinside.com 2019 - 2024. All rights reserved.