Skip to content

Instantly share code, notes, and snippets.

@dimitris-c
Last active February 13, 2018 14:49
Show Gist options
  • Save dimitris-c/c005190beded8a75c2cd6d4f3ee929da to your computer and use it in GitHub Desktop.
Save dimitris-c/c005190beded8a75c2cd6d4f3ee929da to your computer and use it in GitHub Desktop.
CenterCellCollectionViewFlowLayout
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