簡體   English   中英

為什么collectionView單元居中僅在一個方向上起作用?

[英]Why collectionView cell centering works only in one direction?

我正在嘗試在水平滾動中居中對齊單元格。 我已經編寫了一種方法,但是僅當我向右滾動時才有效,向左滾動時它只是滾動而不會停在單元格的中心。

有人可以幫我定義這個錯誤嗎?

class CenterCellCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    if let cv = self.collectionView {
        let cvBounds = cv.bounds
        let halfWidth = cvBounds.size.width * 0.5;
        let proposedContentOffsetCenterX = proposedContentOffset.x + halfWidth;

        if let attributesForVisibleCells = self.layoutAttributesForElementsInRect(cvBounds) {
            var candidateAttributes: UICollectionViewLayoutAttributes?
            for attributes in attributesForVisibleCells {

                // == Skip comparison with non-cell items (headers and footers) == //
                if attributes.representedElementCategory != UICollectionElementCategory.Cell {
                    continue
                }

                if (attributes.center.x == 0) || (attributes.center.x > (cv.contentOffset.x + halfWidth) && velocity.x < 0) {
                    continue
                }

                // == First time in the loop == //
                guard let candAttrs = candidateAttributes else {
                    candidateAttributes = attributes
                    continue
                }

                let a = attributes.center.x - proposedContentOffsetCenterX
                let b = candAttrs.center.x - proposedContentOffsetCenterX

                if fabsf(Float(a)) < fabsf(Float(b)) {
                    candidateAttributes = attributes;
                }
            }

            if(proposedContentOffset.x == -(cv.contentInset.left)) {
                return proposedContentOffset
            }

             return CGPoint(x: floor(candidateAttributes!.center.x - halfWidth), y: proposedContentOffset.y)
        }
    } else {
        print("else")
    }

    // fallback
    return super.targetContentOffsetForProposedContentOffset(proposedContentOffset)
    }
}

在我的UIViewController中:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    var insets = self.collectionView.contentInset
    let value = ((self.view.frame.size.width - ((CGRectGetWidth(collectionView.frame) - 35))) * 0.5)
    insets.left = value
    insets.right = value
    self.collectionView.contentInset = insets

    self.collectionView.decelerationRate = UIScrollViewDecelerationRateNormal
}

如果您有任何問題-請問我

實際上,我只是對另一個線程做了一個略有不同的實現,但是對其進行了調整以適合這個問題。 嘗試以下解決方案:)

/**
 *  Custom FlowLayout
 *  Tracks the currently visible index and updates the proposed content offset
 */
class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {

    // Tracks the currently visible index
    private var visibleIndex : Int = 0

    // The width offset threshold percentage from 0 - 1
    let thresholdOffsetPrecentage : CGFloat = 0.5

    // This is the flick velocity threshold
    let velocityThreshold : CGFloat = 0.4

    override init() {
        super.init()
        self.minimumInteritemSpacing = 0.0
        self.minimumLineSpacing = 0.0
        self.scrollDirection = .Horizontal
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {

        let leftThreshold = CGFloat(collectionView!.bounds.size.width) * ((CGFloat(visibleIndex) - 0.5))
        let rightThreshold = CGFloat(collectionView!.bounds.size.width) * ((CGFloat(visibleIndex) + 0.5))

        let currentHorizontalOffset = collectionView!.contentOffset.x

        // If you either traverse far enough in either direction,
        // or flicked the scrollview over the horizontal velocity in either direction,
        // adjust the visible index accordingly

        if currentHorizontalOffset < leftThreshold || velocity.x < -velocityThreshold {
            visibleIndex = max(0 , (visibleIndex - 1))
        } else if currentHorizontalOffset > rightThreshold || velocity.x > velocityThreshold {
            visibleIndex += 1
        }

        var _proposedContentOffset = proposedContentOffset
        _proposedContentOffset.x = CGFloat(collectionView!.bounds.width) * CGFloat(visibleIndex)

        return _proposedContentOffset
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM