我假设你已经设置了pagingEnabled
对于集合视图。它继承了这个属性UIScrollView
(因为UICollectionView
是一个子类UIScrollView
).
问题在于集合视图使用自己的宽度(帖子中的 320 点)作为页面的宽度。每个单元格的宽度与集合视图相同,但单元格之间有一个 10 磅的“装订线”。这意味着从单元格 0 的左边缘到单元格 1 的左边缘的距离为 320 + 10 = 330 点。因此,当您滚动显示单元格 1 时,集合视图在偏移量 320(其自身宽度)处停止滚动,但单元格 1 实际上从偏移量 330 处开始。
最简单的解决办法可能是关闭pagingEnabled
并通过覆盖自己实现分页scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)
在你的集合视图委托中,如下所示:
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else { return }
let pageWidth = scrollView.bounds.size.width + flowLayout.minimumInteritemSpacing
let currentPageNumber = round(scrollView.contentOffset.x / pageWidth)
let maxPageNumber = CGFloat(collectionView?.numberOfItems(inSection: 0) ?? 0)
// Don't turn more than one more page when decelerating, and don't go beyond the first or last page.
var pageNumber = round(targetContentOffset.pointee.x / pageWidth)
pageNumber = max(0, currentPageNumber - 1, pageNumber)
pageNumber = min(maxPageNumber, currentPageNumber + 1, pageNumber)
targetContentOffset.pointee.x = pageNumber * pageWidth
}
您还需要设置项目尺寸以匹配设备屏幕尺寸,并将减速率设置为快速:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout, let collectionView = collectionView else { return }
flowLayout.itemSize = collectionView.bounds.size
collectionView.decelerationRate = UIScrollViewDecelerationRateFast
}
Result: