UICollectionView setLayout:animation:不保存zIndex

我注意到,当调用setLayout:animatedUICollectionView进行setLayout:animated切换两个布局之间,当前可见的单元格不符合zIndex它的布局属性已在layoutAttributesForItemAtIndexPath:设置layoutAttributesForItemAtIndexPath:

例如,如果我有UICollectionViewUICollectionViewFlowLayout ,将其minimumLineSpacing设置为负数,以便单元格重叠,然后将每个单元格上的zIndex设置为高于以前的单元格,那么它看起来好像单元格从自下而上

但是,如果我将布局设置为另一个布局,然后返回到原始布局,则会中断。 就好像当前可见的单元格不会听取zIndex并放置在其他单元格的顶部。 如果我滚动屏幕外的单元格,然后回到正确的位置。

我曾经也有过一样的问题。 切换布局将忽略单元格的zIndex。

我已经设法通过在z轴上应用翻译来使其“看上去是正确的”,如下所示:

 attributes.transform3D = CATransform3DMakeTranslation(0, 0, indexPath.row); 

但它只是一个视觉修正,如果您尝试点击该项目,您将意识到zIndex仍然是错误的,直到通过将其滚动到屏幕外再循环为止。

我已经设法通过组合grimfrog和Charlie Elliott的反应来获得我所追求的行为。

Charlie Elliott的解决scheme得到了收集视图中项目的正确结果,但是在animation过程中zIndex仍然有一个捕捉效果。

grimfrog的解决scheme提供了正确的外观,但是在布局更改之后仍然存在zIndex仍然不正确的问题,尽pipe看起来正确。

这两者的结合虽然不是一个很好的解决scheme,但是可以工作,并且使用UICollectionViewLayoutAttributes支持的transform和zIndex属性

在我的布局,我有

 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *attributes = [super layoutAttributesForElementsInRect:rect]; [attributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attributes, NSUInteger idx, BOOL *stop) { attributes.zIndex = attributes.indexPath.item + 1; }]; return attributes; } - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath]; attributes.transform3D = CATransform3DMakeTranslation(0, 0, attributes.indexPath.item); return attributes; } 

我不会把这个作为正确的答案,因为我确信必须有另一种方法来解决这个问题,但是我有兴趣看看这个问题是否能够解决其他问题。

尝试:

 // In UICollectionViewCell subclass - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { [super applyLayoutAttributes:layoutAttributes]; // Setting zPosition instead of relaying on // UICollectionView zIndex management 'fixes' the issue self.layer.zPosition = layoutAttributes.zIndex; } 

这一点也是我。 经过多次testing,我意识到UICollectionView将强制选定的单元格位于最前面,而不pipez-index如何。

尝试在以下位置设置z-index:

 - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath; - (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath; 

使用@sampage&@grimfrog作为起点,我可以得到类似的情况

 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path { UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]; attributes.zIndex = path.item; attributes.transform3D = CATransform3DMakeTranslation(0, 0, path.item); // other attribute settings return attributes; } 

我的layoutAttributesForElementsInRect:调用layoutAttributesForItemAtIndexPath:当生成属性数组 – 所以我只需要在那里包含zIndex和transform3D。

我有另一个解决方法。 由于所有的单元格都属于同一个bringSubviewToFront :视图,调用bringSubviewToFront :当单元格显示工作。 具体来说,通过查看Debug View Hierarchy,尽pipeUICollectionViewLayout不根据zIndex渲染单元格,但它仍然按照每个子视图添加到其超级视图的相反顺序显示单元格。