gpt4 book ai didi

ios - 具有自定义 anchorPoint 的 UICollectionViewFlowLayout Cell 重用过早

转载 作者:可可西里 更新时间:2023-11-01 01:35:38 25 4
gpt4 key购买 nike

我将 UICollectionViewFlowLayout 子类化以在水平滚动期间实现小的缩放效果。因此,我不得不继承 UICollectionViewCell 并更改单元格的 layer.anchorPoint(我的缩放比例是从单元格的左下角开始,而不是从默认中心开始).现在一切都很好,除了当我水平滚动时,我的单元格被过早地重复使用(当它突然消失时我仍然可以看到半个单元格)。

我感觉 collection view 的计算仍然基于位于单元格中心的 anchor 来重用单元格...

但是,这是我的收藏 View 。您可以看到项目在到达 Collection View 的左侧时如何变大。这是我想要的缩放比例。 enter image description here

现在我向左滚动。您可以看到右边的项目如何变大,而左边的项目如何离开屏幕。 enter image description here

在这里您可以看到左边的项目并没有离开屏幕,而是已经消失了。只有正确的项目仍然可见:/ enter image description here

所以我想要的是,只有当它的右边界到达屏幕的最左边时,才让左边的项目消失。简单地说,只有当我不再看到它时才消失。

这是我的代码:

class SongsCollectionViewCell : UICollectionViewCell {

@IBOutlet weak var imgAlbumCover: UIImageView!


override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes) {
super.applyLayoutAttributes(layoutAttributes)

//we must change the anchor point for propper cells positioning and scaling
self.layer.anchorPoint.x = 0
self.layer.anchorPoint.y = 1
}

这是布局本身:

class SongsCollectionViewLayout : UICollectionViewFlowLayout {

override func prepareLayout() {
collectionView?.decelerationRate = UIScrollViewDecelerationRateFast
self.scrollDirection = UICollectionViewScrollDirection.Horizontal;

//size of the viewport
let size:CGSize = self.collectionView!.frame.size;
let itemWidth:CGFloat = size.width * 0.7//0.7//3.0;
self.itemSize = CGSizeMake(itemWidth, itemWidth);
self.sectionInset = UIEdgeInsetsMake(0,0,0,0);
self.minimumLineSpacing = 0
self.minimumInteritemSpacing = 0

}

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
return true
}


override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

let attributes:[UICollectionViewLayoutAttributes] = super.layoutAttributesForElementsInRect(rect)!

var visibleRect:CGRect = CGRect()
visibleRect.origin = self.collectionView!.contentOffset;
visibleRect.size = self.collectionView!.bounds.size;

for layoutAttributes in attributes {

if (CGRectIntersectsRect(layoutAttributes.frame, rect)) {

//we must align items to the bottom of the collection view on y axis
let frameHeight = self.collectionView!.bounds.size.height
layoutAttributes.center.y = frameHeight
layoutAttributes.center.x = layoutAttributes.center.x - self.itemSize.width/2

//find where ite, left x is
let itemLeftX:CGFloat = layoutAttributes.center.x

//distance of the item from the left of the viewport
let distanceFromTheLeft:CGFloat = itemLeftX - CGRectGetMinX(visibleRect)
let normalizedDistanceFromTheLeft = abs(distanceFromTheLeft) / self.collectionView!.frame.size.width

//item that is closer to the left is most visible one
layoutAttributes.alpha = 1 - normalizedDistanceFromTheLeft
layoutAttributes.zIndex = abs(Int(layoutAttributes.alpha)) * 10;

//scale items
let scale = min(layoutAttributes.alpha + 0.5, 1)
layoutAttributes.transform = CGAffineTransformMakeScale(scale, scale)

}

}

return attributes;
}

override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
// Snap cells to centre
var newOffset = CGPoint()
let layout = collectionView!.collectionViewLayout as! UICollectionViewFlowLayout
let width = layout.itemSize.width + layout.minimumLineSpacing
var offset = proposedContentOffset.x + collectionView!.contentInset.left

if velocity.x > 0 {
//ceil returns next biggest number
offset = width * ceil(offset / width)
} else if velocity.x == 0 { //6
//rounds the argument
offset = width * round(offset / width)
} else if velocity.x < 0 { //7
//removes decimal part of argument
offset = width * floor(offset / width)
}
newOffset.x = offset - collectionView!.contentInset.left
newOffset.y = proposedContentOffset.y //y will always be the same...
return newOffset
}

最佳答案

回答我自己的问题。所以正如我所怀疑的那样,布局考虑到了旧的中心,这就是为什么我必须在更改 anchor 后立即更正单元格的中心。所以我的自定义单元格现在看起来像这样:

class SongsCollectionViewCell : UICollectionViewCell {

@IBOutlet weak var imgAlbumCover: UIImageView!

override func prepareForReuse() {
imgAlbumCover.hnk_cancelSetImage()
imgAlbumCover.image = nil
}

override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes) {
super.applyLayoutAttributes(layoutAttributes)

//we must change the anchor point for propper cells positioning and scaling
self.layer.anchorPoint.x = 0
self.layer.anchorPoint.y = 1

//we need to adjust a center now
self.center.x = self.center.x - layoutAttributes.size.width/2
}

希望对大家有帮助

关于ios - 具有自定义 anchorPoint 的 UICollectionViewFlowLayout Cell 重用过早,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37998925/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com