我有两个 UICollectionViewLayouts 在单独使用时可以正常工作,但是当使用 setCollectionViewLayout:animated 在两个布局之间切换时:动画布局的 zIndex 不使用它自己的 zIndex 值,而是使用原始的 zIndex 值布局。
以下是这两种布局各自的样子:
在布局 1 中,单元格与顶部的项目 0 堆叠在一起。
在布局 2 中,单元格与底部的项目 0 堆叠在一起。
在布局 1 中,我将 zIndex 设置为:
[attributes setZIndex:100 - [indexPath item]];
在布局 2 中,我将 zIndex 设置为:
[attributes setZIndex:100 + [indexPath item]];
如果我从布局 1 开始并更改为布局 2,我最终会得到以下结果:
如果我从布局 2 开始并更改为布局 1,我最终会得到以下结果:
我已经尝试在 layoutAttributesForElementsInRect: 和 layoutAttributesForItemAtIndexPath: 中设置 zIndex,我发现在切换布局时, layoutAttributesForElelmentsInRect: 在被动画化到的布局上被调用一次,而 layoutAttributesForItemAtIndexPath: 在两个布局上被调用多次随着动画过渡的发生。
我还注意到对 layoutAttributesForItemAtIndexPath: 的调用是在被动画化到的布局上被调用后被动画化的布局调用的。这导致我尝试一些奇怪的事情,即在 layoutAttributesForElementsInRect: 中为给定布局设置正确的 zIndex:但在 layoutAttributesForItemAtIndexPath: 中为其他布局设置 zIndex。这实际上会导致动画在任一方向完成后的正确布局,但从布局 2 到布局 1 的动画看起来很糟糕,因为 zIndex 直到动画结束时才会更新。
这是从布局 2 到布局 1 的动画完成(并更正 zIndex)之前的样子:
为了处理在状态之间看到这个问题,我正在考虑制作一个中间布局,它只在布局 2 转换到布局 1 之前更改布局 2 中单元格的 zIndex。不优雅,但我认为如果我使用 setCollectionViewLayout:animated:completion 可能会起作用:我在第一个布局更改的完成块内调用 setCollectionViewLayout:animated:。
无论如何,对我来说,我应该在 layoutAttributesForItemAtIndexPath: 中为相反的布局设置 zIndex 似乎很疯狂,以便获得更改布局的正确最终结果。有没有人对如何以不需要这种 hack 的方式实现这一点有任何建议?
编辑我在从布局 2 切换到布局 1 时实现了中间布局。中间布局仅在 zIndex 被翻转方面有所不同。有趣的是,要在布局 2 和中间布局之间切换,我不需要在 layoutAttributesForItemAtIndexPath: 中应用 hack:但是我确实需要在 setCollectionViewLayout:animated:completion 的完成块中调用 collectionView 上的 reloadData 以使其工作。
仍然很想知道为什么 zIndex hack 是正确切换其他布局所必需的。