应用平移变换时,UICollectionViewFlowLayout 边缘单元格消失
UICollectionViewFlowLayout edge cells disappear when translation transform is applied
我正在使用自定义 UICollectionViewFlowLayout
使单元格在到达顶部时缩放和淡入淡出。为此,我将 alpha
和 transform
应用于布局属性。这是我的代码 (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)) {
我正在使用自定义 UICollectionViewFlowLayout
使单元格在到达顶部时缩放和淡入淡出。为此,我将 alpha
和 transform
应用于布局属性。这是我的代码 (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)) {