19

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

例如,如果我有一个UICollectionViewwith UICollectionViewFlowLayout,将其设置minimumLineSpacing为负数,以便单元格重叠,然后zIndex在每个单元格上设置 a 高于前一个单元格的值,然后看起来好像单元格是从下往上堆叠的。

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

4

7 回答 7

11

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

通过在 z 轴上应用如下平移,我设法使其“看起来正确”:

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

但这只是一个视觉修复,如果您尝试单击该项目,您将意识到 zIndex 仍然是错误的,直到通过将其滚动到屏幕外来回收它。

于 2012-10-09T08:28:48.760 回答
8

通过结合使用 grimfrog 和 Charlie Elliott 的反应,我设法得到了我所追求的行为。

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

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

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

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

于 2012-10-11T06:20:33.130 回答
7

尝试:

// 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;
}
于 2016-10-13T02:09:52.930 回答
4

这也咬到我了。经过几次测试后,我意识到UICollectionView无论z-index如何,都会强制选定的单元格位于顶部。

于 2012-10-11T09:51:26.840 回答
2

尝试将 z-index 设置为:

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
于 2012-10-05T22:19:20.873 回答
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 。

于 2013-05-15T14:16:15.747 回答
0

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

于 2017-08-11T10:40:40.697 回答