UICollectionView setLayout:animated:不保留zIndex

时间:2012-09-30 06:53:04

标签: ios uicollectionview z-index

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

例如,如果我要UICollectionView UICollectionViewFlowLayout,请将minimumLineSpacing设为负数,以便细胞重叠,然后在每个上设置zIndex单元格高于前一单元格,然后看起来好像单元格从下往上堆叠。

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

7 个答案:

答案 0 :(得分:10)

我遇到了同样的问题。切换布局将忽略单元格的zIndex。

我已经设法让它'#34;看起来正确"通过在z轴上应用这样的翻译:

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

但它只是一个视觉修复,如果你试图点击该项目,你会发现zIndex仍然是错误的,直到通过在屏幕外滚动来回收它。

答案 1 :(得分:8)

我设法通过使用组合grimfrog和Charlie Elliott的回答来获得我所追求的行为。

Charlie Elliott的解决方案为集合视图中的项目获得了正确的最终结果,但在动画期间仍然存在对zIndex的捕捉效果。

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

两者的结合虽然不是一个很好的解决方案,但确实有效,并且确实使用了UICollectionViewLayoutAttributes支持的转换和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;
}

我不会将此作为正确的答案,因为我确信必须有另一种方法来解决这个问题,但我很想知道这是否也解决了其他问题。

答案 2 :(得分:6)

尝试:

// 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;
}

答案 3 :(得分:3)

这也是我的意思。经过多次测试后,我意识到UICollectionView将强制选定的单元格位于顶部,无论z-index如何。

答案 4 :(得分:1)

尝试在:

中设置z-index
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;

答案 5 :(得分:0)

使用@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。

答案 6 :(得分:0)

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