【发布时间】:2021-09-29 02:59:48
【问题描述】:
问题
如何使用组合布局获得水平集合视图部分的完整可滚动内容宽度?
详情
我正在使用组合布局实现UICollectionView,因此我可以获得良好而简单的section.orthogonalScrollingBehavior = .groupPaging 行为。但是,我还需要知道用户滚动浏览该部分的百分比,以便我可以保持自定义 PageControl 同步。对于使用UICollectionViewFlowLayout 的其他集合视图,这是一个简单的计算:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let scrollProgress = scrollView.contentOffset.x / scrollView.contentSize.width
pageControl.currentPercentage = scrollProgress
我已经learned 需要使用visibleItemsInvalidationHandler 而不是这个委托方法。我的问题是,对于组合布局,layoutEnvironment.container.contentSize.width 和 collectionView.contentSize.width 的值不再是 scrollable 内容的全宽,它现在等于 collectionView 本身的框架。不过,scrollOffset 的值是,就完整的可滚动内容大小而言。
section.visibleItemsInvalidationHandler = { [weak self] visibleItems, scrollOffset, layoutEnvironment in
guard let self = self else { return }
let contentWidth = layoutEnvironment.container.contentSize.width // not the full content width
//let contentWidth = self.collectionView.contentSize.width // neither is this!
let scrollProgress = scrollPosition / contentWidth
self.pageControl.currentPercentage = scrollProgress
}
我尝试在layoutEnvironment 中进行挖掘,但没有发现任何内容等于完整的可滚动内容大小。我也尝试过根据单元格的数量计算它,但由于需要考虑 contentOffsets 和组间间距,我无法正确计算。
我的完整布局代码和结果 UI 的屏幕截图如下,以防万一。也许有一种方法可以更改此布局以达到相同的结果并在contentSize 中获得正确的值。
let layout: UICollectionViewLayout = {
let itemWidth = itemSize.width - 2 * Const.margin
let itemLayoutSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemLayoutSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(itemWidth), heightDimension: .fractionalHeight(1.0))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: Const.margin, bottom: 0, trailing: Const.margin)
section.interGroupSpacing = Const.interItemSpacing
section.orthogonalScrollingBehavior = .groupPaging
section.visibleItemsInvalidationHandler = { /* ... */ }
return UICollectionViewCompositionalLayout(section: section)
}()
起始位置:
滚动到下一项:
【问题讨论】:
标签: ios swift uicollectionview uicollectionviewlayout