Skip to content

Instantly share code, notes, and snippets.

@kmikael
Last active March 10, 2021 09:31
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmikael/53a031c5ec421ae43ceff7237f5d8f5b to your computer and use it in GitHub Desktop.
Save kmikael/53a031c5ec421ae43ceff7237f5d8f5b to your computer and use it in GitHub Desktop.
Snapping, centering and automatically sizing flow layout
import UIKit
class HomeCollectionViewFlowLayout: UICollectionViewFlowLayout {
var isSetUp = false
override func prepare() {
super.prepare()
setUpIfNeeded()
}
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
let targetContentOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
guard let collectionView = collectionView, let layoutAttributes = layoutAttributesForElements(in: collectionView.bounds) else {
return targetContentOffset
}
let centerX = collectionView.bounds.width / 2.0
let z = proposedContentOffset.x + centerX
guard let first = layoutAttributes.sorted(by: { abs($0.center.x - z) < abs($1.center.x - z) }).first else {
return targetContentOffset
}
return CGPoint(x: first.center.x - centerX, y: proposedContentOffset.y)
}
}
extension HomeCollectionViewFlowLayout {
func setUpIfNeeded() {
guard let collectionView = collectionView, !isSetUp else {
return
}
collectionView.decelerationRate = UIScrollViewDecelerationRateFast
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
scrollDirection = .horizontal
minimumLineSpacing = 25.0
minimumInteritemSpacing = 0.0
if layoutAttributesForElements(in: collectionView.bounds)?.count == 1 {
itemSize = collectionView.bounds.insetBy(dx: 25.0, dy: 25.0).size
} else {
itemSize = collectionView.bounds.insetBy(dx: 50.0, dy: 25.0).size
}
let leftRight = (collectionView.bounds.width - itemSize.width) / 2.0
sectionInset = UIEdgeInsets(top: 0.0, left: leftRight, bottom: 0.0, right: leftRight)
invalidateLayout()
isSetUp = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment