2014-08-28 63 views
1

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

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

我已经试过

我缓存UICollectionViewLayoutAttributes用于在第一计算单元,使流布局时,系统调用layoutAttributesForItemAtIndexPath引用缓存。以这种方式进行缓存的好处是,当我经常使布局无效时,窗口就会飞出窗口,因为prepareLayout会每次运行它并重新填充缓存。我尝试实现一个系统,其中prepareLayout只会在第一次传递时填充缓存,并在随后的传递中不执行逻辑。这极大地提高了性能,并且工作,但是插入和删除单元格时解决方案崩溃,导致断言失败。

我也对其他粘滞标头的实现和涉及一致失效的类似布局要求做了大量的研究,但这些解决方案都不需要同时解决我所具有的特定于部分的布局问题。因此,他们推荐的解决方案是不可行的。我在这一点上有点出乎我的意料...

回答

0

对于任何有兴趣实现类似的东西的人来说,这里是我遇到的解决方案。这个解决方案避免了需要默认shouldInvalidateLayoutForBoundsChangeYES,节省了大量的CPU开销,同时保持粘性头完好无损。

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