2

我有两个 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 是正确切换其他布局所必需的。

4

1 回答 1

0

在不深入介绍 UICollectionView 架构和布局方法的任何细节的情况下,这里是一个概念性的想法:

鉴于可重复使用的单元格回收 - 您是否可以不简单地将新内容分配给正确位置的单元格*?也就是说,您确保在一个布局中具有项目 0 的顶部单元格在第二个布局中具有最后一个项目。也许它涉及颠倒顺序,但它似乎比算术重新计算 z-index 更明显且更简单。

于 2013-08-09T23:24:00.690 回答