代码之家  ›  专栏  ›  技术社区  ›  Tom Hamming

如何在发生自调整大小之前准确地为uiCollectionViewLayout在rect中提供元素?

  •  2
  • Tom Hamming  · 技术社区  · 6 年前

    我在用 UICollectionView 构建可以在网格或垂直列表布局中显示元素的ui。 UICollectionViewFlowLayout 不能很好地使用全宽度列表布局,所以我正在编写自己的 UICollectionViewLayout 子类。并且行是自调整大小的,因此它们可以有多行标签,并将其字体大小与系统字体大小设置相匹配,并根据需要增大/缩小

    在内部,它具有所有行的布局属性集合。在 prepareLayout 我遍历了数据源中的所有索引路径,并创建布局属性,将其框架设置为估计的行高。

    shouldInvalidateLayoutForPreferredLayoutAttributes ,我返回 YES 如果高度与集合中该行的值不同。然后进入 invalidationContextForPreferredLayoutAttributes ,我将使传入的索引路径之后的所有项无效。 preferredAttributes ,因为此行中的高度更改会影响所有后续行的垂直位置。那么 准备部署 再次调用,并根据需要更新所有内容的帧。

    问题在于这一系列事件:

    • layoutAttributesForElementsInRect 接到电话。我检查了所有的属性 CGRectIntersectsRect(attr.frame, rect) 是的。
    • 应为首选布局属性验证布局 为即将出现的每一行调用。他们中的一些人最终比原先估计的身高要小。

    如果行的总收缩量足够大,一行或两行不在 LayoutAttributesForelementsRect布局 把他们抬起来,让他们出现。例如,如果rect是y值0到1334,则在调用 应为首选布局属性验证布局 现在可能是1300。但是layout对象已经“知道”屏幕上应该有哪些行,所以这些行不会显示出来,而且我的列表中还有漏洞。

    我可以通过返回 LayoutAttributesForelementsRect布局 (通过展开矩形,我可以得到100个垂直点或其他东西)。但这是一个黑客,而且这似乎是api应该有办法解决的问题。但我再也没接到电话 LayoutAttributesForelementsRect布局 完成自定尺寸后,我不想再通过 UICollectionViewLayoutInvalidationContext 是的。

    所以…我在api中遗漏了一些明显的东西吗?这是不是一个不应该发生的问题,这意味着我正在处理一些错误的事情?似乎没有办法准确回答 LayoutAttributesForelementsRect布局 在自动调整大小之前…?

    说明问题的示例代码是 here 在吉瑟布上。

    1 回复  |  直到 6 年前
        1
  •  2
  •   brynbodayle    6 年前

    我发现 invalidationContextForPreferredLayoutAttributes 当您有自调整大小的补充视图时,将导致一个错误,使您得到布局间隙。我也犯了同样的错误,其他人也犯了同样的错误,因为下面的项目无效,并且项目是自大小的,这似乎是合乎逻辑的。我猜collection视图会为您处理这个问题。

    这些 are the lines 要在示例项目中删除:

    [result invalidateItemsAtIndexPaths:rowPaths];
    [result invalidateSupplementaryElementsOfKind:UICollectionElementKindSectionHeader atIndexPaths:headerPaths];
    

    我已经向苹果提交了一份文件更新雷达。 http://www.openradar.me/35833995