UICollectionViewFlowLayout

UICollectionViewFlowLayout

我需要保持UICollectionViewCell中心在纵向模式下对齐。
最终结果应为:
animation

我正在使用此代码执行此操作:

override public func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {

var layoutAttributes: Array = layoutAttributesForElements(in: collectionView!.bounds)!

if layoutAttributes.count == 0 {
    return proposedContentOffset
}

var firstAttribute: UICollectionViewLayoutAttributes = layoutAttributes[0]

for attribute: UICollectionViewLayoutAttributes in layoutAttributes {
    if attribute.representedElementCategory != .cell {
        continue
    }

    if((velocity.x >= 0.0 && attribute.center.x > firstAttribute.center.x) ||
        (velocity.x <= 0.0 && attribute.center.x < firstAttribute.center.x)) {
        firstAttribute = attribute;
    }
}

return CGPoint(x: firstAttribute.center.x -

collectionView!.bounds.size.width * 0.5, y: proposedContentOffset.y)
}

这对所有单元格都适用,但最后一个单元格在滚动时不会居中对齐。

实际结果:

ios - “targetContentOffset” UICollectionViewFlowLayout无法正常工作-LMLPHP

有什么办法解决这个问题?

最佳答案

为了使UICollectionViewCell居中,您需要更改UICollectionViewFlowLayoutUICollectionView,即制作UICollectionViewFlowLayout的子类,并将其设置为UICollectionView's中的storyboard布局。

1. UICollectionViewFlowLayout子类

class CollectionViewFlowLayout: UICollectionViewFlowLayout
{
    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
    {
        if let collectionViewBounds = self.collectionView?.bounds
        {
            let halfWidthOfVC = collectionViewBounds.size.width * 0.5
            let proposedContentOffsetCenterX = proposedContentOffset.x + halfWidthOfVC
            if let attributesForVisibleCells = self.layoutAttributesForElements(in: collectionViewBounds)
            {
                var candidateAttribute : UICollectionViewLayoutAttributes?
                for attributes in attributesForVisibleCells
                {
                    let candAttr : UICollectionViewLayoutAttributes? = candidateAttribute
                    if candAttr != nil
                    {
                        let a = attributes.center.x - proposedContentOffsetCenterX
                        let b = candAttr!.center.x - proposedContentOffsetCenterX
                        if fabs(a) < fabs(b)
                        {
                            candidateAttribute = attributes
                        }
                    }
                    else
                    {
                        candidateAttribute = attributes
                        continue
                    }
                }

                if candidateAttribute != nil
                {
                    return CGPoint(x: candidateAttribute!.center.x - halfWidthOfVC, y: proposedContentOffset.y);
                }
            }
        }
        return CGPoint.zero
    }
}

2. UICollectionViewDelegateFlowLayout方法
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    let cellSize = CGSize(width: collectionView.bounds.width - (2 * kCellSpacing) - (2 * kCellInset), height: collectionView.bounds.height)
    return cellSize
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
{
    return kCellSpacing
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
    let sectionInset = UIEdgeInsetsMake(0, kCellSpacing + kCellInset, 0, kCellSpacing + kCellInset)
    return sectionInset
}

检查上面的代码,让我知道这是否满足您的要求。

10-08 04:52