【问题标题】:UICollectionView not obeying zIndex of UICollectionViewLayoutAttributesUICollectionView 不遵守 UICollectionViewLayoutAttributes 的 zIndex
【发布时间】:2015-07-29 10:15:45
【问题描述】:

我想要达到的效果是一种粘性标题单元格。对我来说重要的是粘性单元格漂浮在其他单元格的顶部。有点像这样:

┌──────────┐ 
│          │ 
│  Cell 0  │ 
│          ├┐
└┬─────────┘│
 │  Cell 4  │
 │          │
 └──────────┘
 ┌──────────┐
 │          │
 │  Cell 5  │
 │          │
 └──────────┘
 ┌──────────┐
 │          │
 │  Cell 6  │
 │          │
 └──────────┘

单元格 4、5 和 6 通常是可见的,我在 layoutAttributesForElementsInRect: 期间在我的 UICollectionViewFlowLayout 子类中构造单元格 0 的属性。我所做的就是调用超级实现,确定我需要添加哪个单元格,然后构造UICollectionViewLayoutAttributes(forCellWithIndexPath:)。然后我将zIndex 设置为1(默认为0)。

我遇到的问题是UICollectionView 似乎总是忽略zIndex

┌──────────┐ 
│          │ 
│  Cell 0  │ 
│┌─────────┴┐
└┤          │
 │  Cell 4  │
 │          │
 └──────────┘
 ┌──────────┐
 │          │
 │  Cell 5  │
 │          │
 └──────────┘
 ┌──────────┐
 │          │
 │  Cell 6  │
 │          │
 └──────────┘

现在我相信可以使用 3d 变换在视觉上对其进行排序,但这对我不起作用,因为我不希望任何点击进入顶部的单元格。所以在这个例子中,我不希望 Cell 4 接收用于 Cell 0 的点击。

有人有什么想法吗?这是在 iOS 8.4 上。

【问题讨论】:

    标签: ios uikit uicollectionview uicollectionviewcell


    【解决方案1】:

    由于 UIKit 错误,无法更新 UICollectionViewLayoutAttributes.zIndex

    这段代码可以解决问题:

    // In your UICollectionViewCell subclass:
    override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
        super.apply(layoutAttributes)
        layer.zPosition = CGFloat(layoutAttributes.zIndex) // or any zIndex you want to set
    }
    

    【讨论】:

    • 谢谢!有效。我想知道,这真的是 UIKit 错误还是我自己的错误?你看到有这个错误的票吗?
    • @surfrider UIKit 是一个非常有问题的地方。这也是我改用 Flutter 的原因之一。
    【解决方案2】:

    在 UICollectionViewLayout 中设置 zIndex 对我不起作用

    我在 UICollectionViewController 的方法中设置了 zIndex

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    customCell.layer.zPosition = 0;
    }
    

    我最好的猜测是布局和控制器之间的某些东西将 zIndex 设置为奇怪的东西

    【讨论】:

    • 你是天才阿杰!感谢您发布解决方案。
    • 最好将此代码放入 UICollectionViewCell 方法中 - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes(您必须继承 UICollectionViewCell 才能这样做)。
    【解决方案3】:

    我创建了一个独立项目,以去除我所有无关的代码。在这个过程中,我想我找到了自己的解决方案。

    override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?

    override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?

    也没有应用新的zIndex,所以我认为这是造成它的原因。

    只是想我应该发回解决方案,以防万一在搜索其他人时出现。

    【讨论】:

    • 那么这里的解决方案是什么?你能说得更具体点吗?
    • 我遇到了同样的问题,这个解决方案对我不起作用。最初加载内容时,它看起来不错,但在我删除了几个部分后,我的单元格的 zIndexes 都搞砸了。
    • 我想我解决了。您必须覆盖处理首选属性失效的方法,以更新新属性的 zIndex。
    • 没用...我想知道为什么。已经很多年了,Apple 仍然没有解决这个问题。
    • @LilyBallard 对我不起作用。如果你有一个完整的解决方案,你可以发布它:)
    【解决方案4】:

    您需要设置这两个值。 zIndex3DTransform 参数。

    class HeaderUnderCellsLayout: UICollectionViewFlowLayout {
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let attributesArray = super.layoutAttributesForElements(in: rect) else { return nil }
    
            attributesArray.forEach { attributes in
                if attributes.representedElementCategory == .supplementaryView && attributes.representedElementKind == UICollectionView.elementKindSectionHeader {
                    attributes.transform3D = CATransform3DMakeTranslation(0, 0, -10)
                    attributes.zIndex = -200
                }
            }
            return attributesArray
        }
    
        override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)
            attributes?.transform3D = CATransform3DMakeTranslation(0, 0, -10)
            attributes?.zIndex = -200
            return attributes
        }
    }
    

    【讨论】:

      【解决方案5】:

      我在UICollectionViewLayout 的子类中遇到了类似的问题,其中单元格的记录不尊重UICollectionViewLayoutAttributes.zIndex 的更新,但我能够通过重新加载移动的单元格来解决这个问题。

      我特别用了这个:

          collectionView.performBatchUpdates({
              collectionView.moveItem(at:indexPath, to:newIndexPath)
          })
      
          collectionView.reloadItems(at: [indexPath, newIndexPath])
      

      【讨论】:

        【解决方案6】:

        iOS 14 上似乎仍在发生这种情况。这就是我设法修复它的方法:

            func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
            {
                guard let attributes = collectionView.collectionViewLayout.layoutAttributesForItem(at: indexPath) else
                {
                    assert(false)
                    return
                }
                cell.layer.zPosition = CGFloat(attributes.zIndex)
            }
            func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath)
            {
                guard let attributes = collectionView.collectionViewLayout.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath) else
                {
                    assert(false)
                    return
                }
                view.layer.zPosition = CGFloat(attributes.zIndex)
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-21
          • 2013-10-13
          • 1970-01-01
          • 2016-12-24
          • 2016-08-29
          • 2023-03-13
          • 2011-02-13
          • 1970-01-01
          相关资源
          最近更新 更多