应用平移变换时,UICollectionViewFlowLayout 边缘单元格消失

UICollectionViewFlowLayout edge cells disappear when translation transform is applied

我正在使用自定义 UICollectionViewFlowLayout 使单元格在到达顶部时缩放和淡入淡出。为此,我将 alphatransform 应用于布局属性。这是我的代码 (link to full demo repo):

class EdgeZoomLayout: UICollectionViewFlowLayout {

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let collectionView = collectionView else { return nil }
        let rectAttributes = super.layoutAttributesForElements(in: rect)!.map { [=10=].copy() as! UICollectionViewLayoutAttributes }
        let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.frame.size)

        for attributes in rectAttributes where attributes.frame.intersects(visibleRect) {
            let positionInFrameY = attributes.center.y - visibleRect.origin.y /// y origin of rectangle
            let cutoff = CGFloat(30)
            
            if positionInFrameY <= cutoff {
                let translation = cutoff - positionInFrameY /// distance from the cutoff, 0 if exactly on cutoff
                let alpha = 1 - (translation / 100)
                let scale = 1 - (translation / 1000)
                
                attributes.alpha = alpha
                attributes.zIndex = Int(alpha >= 1 ? 1 : 0) /// if alpha is 1, keep on the top
                attributes.transform = CGAffineTransform(scaleX: scale, y: scale).translatedBy(x: 0, y: translation)
            } else {
                attributes.zIndex = 1 /// keep on top if not getting zoomed
            }
        }

        return rectAttributes
    }

    /// boilerplate code
    override init() { super.init() }
    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true }
    override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext {
        let context = super.invalidationContext(forBoundsChange: newBounds) as! UICollectionViewFlowLayoutInvalidationContext
        context.invalidateFlowLayoutDelegateMetrics = newBounds.size != collectionView?.bounds.size
        return context
    }
}

这几乎是完美的,但是最上面的单元格在靠近边缘时突然消失了:

如何使单元格缩放和淡入淡出而不像那样消失?我认为这可能是因为集合视图回收了单元格...但是,我该如何保留它?

你要么删除这行

where attributes.frame.intersects(visibleRect)

或者你可以通过这个

visibleRect加点
for attributes in rectAttributes where attributes.frame.intersects(visibleRect.insetBy(dx: 0, dy: -15)) {