Reputation: 57
I'm trying to center the uicollectionview cell while paging enable, but when I slide it, it does not stay centered! I would want it to be just like the image below!
collectionView.dataSource = self
collectionView.delegate = self
collectionView.alwaysBounceHorizontal = true
collectionView.isPagingEnabled = true
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let inset: CGFloat = calculateSectionIntet()
return CGSize(width: view.frame.width - inset * 2, height: view.frame.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 16
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let inset: CGFloat = calculateSectionIntet()
return UIEdgeInsets(top: 0, left: inset, bottom: 0 , right: inset)
}
func calculateSectionIntet() -> CGFloat {
return 32
}
Image:
Upvotes: 0
Views: 388
Reputation: 386
Swift solution(Originally Objective-C) from a 2012 WWDC video.
Subclass UICollectionViewFlowLayout
and override
this function:
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = collectionView else { return .zero }
// Add some snapping behaviour so that the zoomed cell is always centered
let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionView.frame.width, height: collectionView.frame.height)
guard let rectAttributes = super.layoutAttributesForElements(in: targetRect) else { return .zero }
var offsetAdjustment = CGFloat.greatestFiniteMagnitude
let horizontalCenter = proposedContentOffset.x + collectionView.frame.width / 2
for layoutAttributes in rectAttributes {
let itemHorizontalCenter = layoutAttributes.center.x
if (itemHorizontalCenter - horizontalCenter).magnitude < offsetAdjustment.magnitude {
offsetAdjustment = itemHorizontalCenter - horizontalCenter
}
}
return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
}
Also for better snapping, add this to the collectionView's
viewController
:
collectionView.decelerationRate = .fast
Upvotes: 1