【发布时间】:2017-04-14 13:51:06
【问题描述】:
我有一个与我的 CollectionView 大小相同的 collectionView 单元格,即屏幕上一次显示一个单元格,我希望单元格之间的最小间隔为 10,问题是当我滚动单元格时,单元格不是' t 适合整个屏幕,每次滚动后增加单元格的移动。 (查看屏幕截图以获得更好的理解)
【问题讨论】:
标签: ios uicollectionview
我有一个与我的 CollectionView 大小相同的 collectionView 单元格,即屏幕上一次显示一个单元格,我希望单元格之间的最小间隔为 10,问题是当我滚动单元格时,单元格不是' t 适合整个屏幕,每次滚动后增加单元格的移动。 (查看屏幕截图以获得更好的理解)
【问题讨论】:
标签: ios uicollectionview
我假设你已经为集合视图设置了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
}
结果:
【讨论】:
原因是你在设置单元格宽度(320)时没有使用minimum separation of 10。因此,每次滚动都会累积此10。
所以你必须在设置宽度时从 320 中减去 10,所以宽度应该是 310 IMO。
【讨论】: