Sizing supplementary views with auto layout in a custom UICollectionViewLayout

时间:2022-11-13 09:00:38

I am looking for the best way to use auto layout to calculate the size of supplementary views in a custom UICollectionViewLayout. For the purposes of clarity this is a simplified explanation of what I am trying to achieve.

我正在寻找使用自动布局来计算自定义UICollectionViewLayout中补充视图大小的最佳方法。为了清楚起见,这是我想要实现的简化解释。

I have a header supplementary view ACVHeaderView with auto layout constraints.

我有一个标题补充视图ACVHeaderView具有自动布局约束。

In prepareLayout: I want to calculate the size of the section header and create supplementary view layout attributes for it. Then I want to iterate through the cells in that section, creating and storing layout attributes for the cells. Having 'built' the layout these attributes will all be stored to be returned by the other collection view layout methods.

在prepareLayout中:我想计算节头的大小并为其创建补充视图布局属性。然后我想迭代该部分中的单元格,为单元格创建和存储布局属性。在“构建”布局后,这些属性将全部存储为由其他集合视图布局方法返回。

Ideally I want to size the header by calling collectionView:dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:, perform an auto-layout pass and then use view:systemLayoutSizeFittingSize:. This is exactly what I do for the cells themselves (following some example code I got from WWDC).

理想情况下,我想通过调用collectionView:dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:来调整头的大小,执行自动布局传递,然后使用view:systemLayoutSizeFittingSize:。这正是我为单元格本身所做的(遵循我从WWDC获得的一些示例代码)。

However this fails with this error:

但是这会因此错误而失败:

2014-09-04 18:51:53.852 ACV[7298:167827] *** Assertion failure in -[UICollectionViewData layoutAttributesForSupplementaryElementOfKind:atIndexPath:], /SourceCache/UIKit_Sim/UIKit-3302.3.1/UICollectionViewData.m:853
2014-09-04 18:51:53.916 ACV[7298:167827] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for layout attributes for supplementary view UICollectionElementKindSectionHeader in section 0 when there are only 0 sections in the collection view'

I understand the problem I think... I am trying to dequeue a supplementary view for the header before I have sized any cells in that section. That means I have not yet created any layout attributes for any cells in that section (using UICollectionViewLayoutAttributes.forCellWithIndexPath:). UICollectionViewData looks like an internal class that tracks layout attributes in a UICollectionView and it won't allow me to dequeue a supplementary view before there are layout attributes for at least one cell.

我理解我认为的问题......在我调整该部分中的任何单元格之前,我试图将标题的补充视图出列。这意味着我还没有为该部分中的任何单元格创建任何布局属性(使用UICollectionViewLayoutAttributes.forCellWithIndexPath :)。 UICollectionViewData看起来像一个跟踪UICollectionView中的布局属性的内部类,它不允许我在至少有一个单元格的布局属性之前将补充视图出列。

I have thought of the following:

我想到了以下几点:

  1. I could layout the cells first and then the header. However, that makes the logic for setting the cell frames more complicated because they depend on the height of the header.
  2. 我可以先布置单元格,然后是标题。但是,这使得设置单元框架的逻辑更加复杂,因为它们取决于标题的高度。

  3. I could create a 'dummy' attributes for a cell, create and size the header, then update the dummy attributes when I layout the first real cell. This is not difficult but neither is it very clean!
  4. 我可以为单元格创建“虚拟”属性,创建和调整标题大小,然后在布局第一个真实单元格时更新虚拟属性。这不难,但也不是很干净!

  5. I could manually create an instance of ACVHeaderView to use for the purpose of sizing headers. That would work, but in my real-world case I have multiple supplementary views. It seems untidy to have to keep my own record of supplementary kinds and reuse identifiers and a dictionary of prototype views. I would be duplicating the logic used in the collection view dequeuing mechanism.
  6. 我可以手动创建一个ACVHeaderView实例,用于调整标题大小。这样可行,但在我的实际案例中,我有多个补充意见。保持我自己的补充类型记录并重用标识符和原型视图字典似乎是不整洁的。我将复制集合视图出列机制中使用的逻辑。

What is the best way to achieve this? I imagine I must be missing something more straightforward because Apple are encouraging developers to make proper use of dynamic type and auto-layout.

实现这一目标的最佳方法是什么?我想我必须错过更直接的东西,因为Apple鼓励开发人员正确使用动态类型和自动布局。

1 个解决方案

#1


0  

It is possible to have a section with 0 cells in the section, so that shouldn't cause this issue. I think the issue is that you added a header's supplementary attributes, but the section is not available (numberOfSectionsInCollectionView returns 0).

部分中可能有一个包含0个单元格的部分,因此不应该导致此问题。我认为问题是您添加了标头的补充属性,但该部分不可用(numberOfSectionsInCollectionView返回0)。

I would make sure numberOfSectionsInCollectionView: doesn't return 0, when you add your supplementary header attributes.

当你添加你的补充头属性时,我会确保numberOfSectionsInCollectionView:不返回0。

#1


0  

It is possible to have a section with 0 cells in the section, so that shouldn't cause this issue. I think the issue is that you added a header's supplementary attributes, but the section is not available (numberOfSectionsInCollectionView returns 0).

部分中可能有一个包含0个单元格的部分,因此不应该导致此问题。我认为问题是您添加了标头的补充属性,但该部分不可用(numberOfSectionsInCollectionView返回0)。

I would make sure numberOfSectionsInCollectionView: doesn't return 0, when you add your supplementary header attributes.

当你添加你的补充头属性时,我会确保numberOfSectionsInCollectionView:不返回0。