Last active
February 13, 2018 14:49
-
-
Save dimitris-c/c005190beded8a75c2cd6d4f3ee929da to your computer and use it in GitHub Desktop.
CenterCellCollectionViewFlowLayout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CenterCellCollectionViewFlowLayout: UICollectionViewFlowLayout { | |
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { | |
guard let collectionView = self.collectionView else { | |
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) | |
} | |
if collectionView.numberOfItems(inSection: 0) == 0 { | |
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset) | |
} | |
if let first = layoutAttributesForItem(at: IndexPath(item: 0, section: 0)), | |
let last = layoutAttributesForItem(at: IndexPath(item: collectionView.numberOfItems(inSection: 0) - 1, section: 0)) | |
{ | |
let left = (collectionView.frame.width - first.bounds.size.width) * 0.5 | |
let right = (collectionView.frame.width - last.bounds.size.width) * 0.5 | |
sectionInset = UIEdgeInsets(top: 0, left: left, bottom: 0, right: right) | |
} | |
let collectionViewSize = collectionView.bounds.size | |
let proposedContentOffsetCenterX = proposedContentOffset.x + collectionViewSize.width * 0.5 | |
let proposedRect = collectionView.bounds | |
var candidateAttributes: UICollectionViewLayoutAttributes? | |
if let layoutAttributes = self.layoutAttributesForElements(in: proposedRect) { | |
for attributes in layoutAttributes { | |
if attributes.representedElementCategory != .cell { | |
continue | |
} | |
let currentOffset = collectionView.contentOffset | |
let currentPosition = (currentOffset.x + collectionViewSize.width * 0.5) | |
if (attributes.center.x <= currentPosition && velocity.x > 0) || (attributes.center.x >= currentPosition && velocity.x < 0) { | |
continue | |
} | |
if candidateAttributes == nil { | |
candidateAttributes = attributes | |
continue | |
} | |
let lastCenterOffset = candidateAttributes!.center.x - proposedContentOffsetCenterX | |
let centerOffset = attributes.center.x - proposedContentOffsetCenterX | |
if fabsf(Float(centerOffset)) < fabsf(Float(lastCenterOffset)) { | |
candidateAttributes = attributes | |
} | |
} | |
} | |
if candidateAttributes != nil { | |
return CGPoint(x: candidateAttributes!.center.x - collectionViewSize.width * 0.5, y: proposedContentOffset.y) | |
} else { | |
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment