UICollectionViewFlowLayout

UICollectionViewFlowLayout

本文介绍了“目标内容偏移"UICollectionViewFlowLayout 无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在纵向模式下保持 UICollectionViewCell 中心对齐.
最终结果应该是这样的:

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

解决方案

为了保持UICollectionViewCell居中,你需要改变UICollectionViewUICollectionViewFlowLayoutUICollectionViewFlowLayout/代码>,即制作 UICollectionViewFlowLayout 的子类,并在 storyboard 中将其设置为 UICollectionView's Layout.

1.UICollectionViewFlowLayout 子类

class CollectionViewFlowLayout: UICollectionViewFlowLayout{覆盖 func targetContentOffset(forProposedContentOffset proposalContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) ->CG点{如果让 collectionViewBounds = self.collectionView?.bounds{让 halfWidthOfVC = collectionViewBounds.size.width * 0.5让proposedContentOffsetCenterX = proposalContentOffset.x + halfWidthOfVCif let attributesForVisibleCells = self.layoutAttributesForElements(in: collectionViewBounds){varCandidateAttribute:UICollectionViewLayoutAttributes?对于attributesForVisibleCells 中的属性{让 candAttr : UICollectionViewLayoutAttributes?= 候选属性如果 candAttr != nil{让 a = attributes.center.x - proposalContentOffsetCenterX让 b = candAttr!.center.x - proposalContentOffsetCenterX如果晶圆厂(a) 

2.UICollectionViewDelegateFlowLayout 方法

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) ->CG尺寸{让 cellSize = CGSize(width: collectionView.bounds.width - (2 * kCellSpacing) - (2 * kCellInset), height: collectionView.bounds.height)返回单元格大小}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) ->CGFloat{返回 kCellSpacing}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) ->UIEdgeInsets{let sectionInset = UIEdgeInsetsMake(0, kCellSpacing + kCellInset, 0, kCellSpacing + kCellInset)返回部分插入}

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

I have a requirement to keep UICollectionViewCell center aligned in portrait mode.
Final result should be like :animation

I'm using this code to do this:

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)
}

This works fine for all cell except the last cell which doesn't get center aligned upon scrolling.

Actual result:

Is there any way to resolve this issue?

解决方案

To keep the UICollectionViewCell in center, you need to change the UICollectionViewFlowLayout of UICollectionView,i.e. make subclass of UICollectionViewFlowLayout and set it as UICollectionView's Layout in storyboard.

1. UICollectionViewFlowLayout subclass

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 methods

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
}

Check the above code and let me know if this satisfy your requirement.

这篇关于“目标内容偏移"UICollectionViewFlowLayout 无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 02:31