Skip to content

Instantly share code, notes, and snippets.

@abhi21git
Last active July 24, 2023 14:08
Show Gist options
  • Save abhi21git/92a095e1cda6de2e078f676ad2f7d066 to your computer and use it in GitHub Desktop.
Save abhi21git/92a095e1cda6de2e078f676ad2f7d066 to your computer and use it in GitHub Desktop.
Make your cells perfectly scroll to content
class CollectionSnapFlowLayout: UICollectionViewFlowLayout {
var onlyScrollToNext: Bool = true
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView else {
let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
return latestOffset
} /// Add some snapping behaviour so that the cell is always centered
var proposedX: CGFloat = proposedContentOffset.x
if velocity.x >= 0, onlyScrollToNext {
proposedX = min(proposedContentOffset.x, collectionView.contentOffset.x + (itemSize.width) / 2)
} else if velocity.x < 0, onlyScrollToNext {
proposedX = max(proposedContentOffset.x, collectionView.contentOffset.x - (itemSize.width) / 2)
}
let targetRect = CGRect(x: proposedX, y: proposedContentOffset.y, width: collectionView.frame.width, height: collectionView.frame.height)
guard let rectAttributes = super.layoutAttributesForElements(in: targetRect) else { return .zero }
let horizontalCenter = proposedX + collectionView.frame.width / 2
var offsetAdjustment: CGFloat = .greatestFiniteMagnitude
for layoutAttributes in rectAttributes {
let itemHorizontalCenter = layoutAttributes.center.x
if (itemHorizontalCenter - horizontalCenter).magnitude < offsetAdjustment.magnitude {
offsetAdjustment = itemHorizontalCenter - horizontalCenter
}
}
return CGPoint(x: proposedX + offsetAdjustment, y: proposedContentOffset.y)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment