![](/img/trans.png)
[英]Any idea why the following UIView animation only works in one direction?
[英]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.