具有特定于部分的布局和粘性标题的 UICollectionView

Posted

技术标签:

【中文标题】具有特定于部分的布局和粘性标题的 UICollectionView【英文标题】:UICollectionView with section-specific layouts and sticky headers 【发布时间】:2014-08-28 22:05:50 【问题描述】:

我正在构建一个包含两个部分的 UICollectionView。每个部分都有自己的布局 - 第一部分是 2×y 网格,第二部分是 3×y 网格。除了特定于部分的布局之外,我还需要粘性标题(例如默认合并到 UITableViews 中的标题)。

我已经构建了一个功能齐全的 UICollectionViewFlowLayout 子类,它可以适当地处理特定于部分的布局和粘性标题。但是,该解决方案不能很好地扩展到任何部分中超过 250 多个单元格。我做了一些分析和调查,问题的根源似乎是shouldInvalidateLayoutForBoundsChange。我在我的子类中返回YES,因为在用户滚动时需要动态计算我的补充视图(标题)。这会导致补充视图和单元格布局失效,这意味着流程布局会一遍又一遍地在单元格上调用prepareLayout,尽管单元格布局实际上并不需要失效,因为它们并没有改变。当每个刷新周期需要布局的单元数达到数百或数千时,性能就会显着下降。

我的尝试

我在第一次计算时缓存了单元格的UICollectionViewLayoutAttributes,允许流布局在系统调用layoutAttributesForItemAtIndexPath时引用缓存。当我不断地使布局无效时,以这种方式缓存的优势就消失了,因为prepareLayout 每次都会运行它并重新填充缓存。我尝试实现一个系统,其中prepareLayout 只会在第一遍时填充缓存,而在后续遍中不执行任何逻辑。这极大地提高了性能并且有效,但是在插入和删除单元格时解决方案会崩溃,从而导致断言失败。

我还对粘性标题的其他实现和涉及一致失效的类似布局要求进行了大量研究,但这些解决方案都不需要同时解决我遇到的特定于部分的布局问题。因此,他们推荐的解决方案是不可行的。我对这个有点不太了解......

【问题讨论】:

【参考方案1】:

对于有兴趣实现类似功能的任何人,这是我得出的解决方案。此解决方案无需将默认 shouldInvalidateLayoutForBoundsChange 设置为 YES,从而节省大量 CPU 开销,同时保持粘性标头完好无损。

我手动将我的标题添加为self.collectionView 的子视图,并编写了一个跟踪self.collectionView.contentOffset.y 的方法,以便在内容滚动时适当地浮动和粘贴标题。这个解决方案的一个警告是它不能很好地扩展到更多的部分。通过手动添加视图,您将失去UICollectionReusableView 的一些好处,例如出队和回收。在我的实现中,最多有 5 个部分,因此牺牲很小。

【讨论】:

以上是关于具有特定于部分的布局和粘性标题的 UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章

带有 socket.io 的单页应用程序中的特定于部分的侦听器

如何创建具有特定于每个方面的标题和副标题的分面图?

如何使用特定于应用程序的值覆盖共享库中的 sass 变量

包括特定于 ASP.NET MVC4 视图或部分视图的脚本

具有特定于案例值的 YAML 可重用变量

我想在原生 App 的 Android Xamarin 布局中使图像具有粘性。我正在使用 axml 进行布局渲染 [关闭]