当 UICV 布局无效时,UICollectionViewCell 无法重新布局其子视图

UICollectionViewCell fails to relayout its subviews when UICV layout is invalidated

关于这个问题,我写了更多 detailed blog post,但这是要点。我在另一个 UIViewController 中嵌入了 UICollectionView。当容器视图更改其边界时,集合视图也更改其边界,从而触发其 UICollectionViewLayout 重新布局。

除了单元格不使用旧边界重新使用新框架和布局外,一切都很好。 这是重要方法的日志,其中很明显 layoutSubviews 使用了错误的(旧的)框架。

__57-[RTColumnViewController processCalculatorKeypadVisible:]_block_invoke

-[RTUnitLayout shouldInvalidateLayoutForBoundsChange:] : YES, {{0, 1014}, {272, 375}} -> {{0, 1014}, {175, 375}}
-[RTUnitLayout prepareLayout], bounds={{0, 1014}, {175, 375}}, itemsize={175, 89}
-[RTUnitLayout prepareForAnimatedBoundsChange:] : {{0, 1014}, {272, 375}} -> {{0, 1014}, {175, 375}}

-[RTUnitLayout layoutAttributesForElementsInRect:] : rect={{0, 667}, {175, 1334}}
__50-[RTUnitLayout layoutAttributesForElementsInRect:]_block_invoke_2 : <NSIndexPath: 0xc000000000048016> {length = 2, path = 0 - 9} frame={{0, 801}, {175, 89}}
__50-[RTUnitLayout layoutAttributesForElementsInRect:]_block_invoke_2 : <NSIndexPath: 0xc000000000058016> {length = 2, path = 0 - 11} frame={{0, 979}, {175, 89}}
...

-[RTUnitLayout finalLayoutAttributesForDisappearingItemAtIndexPath:] : <NSIndexPath: 0xc000000000058016> {length = 2, path = 0 - 11} frame={{0, 979}, {272, 89}}
-[RTUnitLayout initialLayoutAttributesForAppearingItemAtIndexPath:] : <NSIndexPath: 0xc000000000058016> {length = 2, path = 0 - 11} frame={{0, 979}, {175, 89}}
-[RTUnitCell layoutSubviews] : pre-super: {{0, 979}, {272, 89}}
-[RTUnitCell layoutSubviews] : post-super: {{0, 979}, {272, 89}}
...

-[RTUnitLayout finalizeAnimatedBoundsChange] : {{0, 1014}, {175, 375}}

__57-[RTColumnViewController processCalculatorKeypadVisible:]_block_invoke623 : completed

完成后,如果我轻轻滚动UICV,它会触发重新显示,所有单元格都会按应有的方式显示。我只是很困惑,为什么在原始动画中应该发生这种情况却没有发生。

有什么想法吗?

Apple 工程师回复。如果您有 UICollectionViewLayoutAttributes 的自定义子类,请不要像我一样犯愚蠢的错误 return YES form isEqual: method.

必须是:

- (BOOL)isEqual:(id)other {
...
return [super isEqual:other];
}

我的 blog post 中有更多详细信息。