我正在实施UICollectionViewCompositionalLayout
和使用
section.orthogonalScrollingBehavior = .groupPagingCentered
水平滚动一个部分。
这允许用户在一个部分中从一个页面水平滚动到另一个页面。
我用
section.visibleItemsInvalidationHandler = {...}
获取用户滚动到的页面。
如何以编程方式滚动到本节中的页面?
我正在实施UICollectionViewCompositionalLayout
和使用
section.orthogonalScrollingBehavior = .groupPagingCentered
水平滚动一个部分。
这允许用户在一个部分中从一个页面水平滚动到另一个页面。
我用
section.visibleItemsInvalidationHandler = {...}
获取用户滚动到的页面。
如何以编程方式滚动到本节中的页面?
我真的让它工作了。此代码适用于 XCode 12 Beta 2 / Target iOS14 / Swift 5.1。
在这段代码中,要特别注意间距、插入和正交滚动行为!!!
fileprivate func configureCollectionViewLayout() {
func createLayout() -> UICollectionViewLayout {
self.collectionView.canCancelContentTouches = false
let layout = UICollectionViewCompositionalLayout {
(sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
guard let sectionKind = Section(rawValue: sectionIndex) else { return nil }
let spacing = CGFloat(10)
switch sectionKind {
case .someOtherSection:
// configure the layout for this section
case .yetAnotherSection:
// configure the layout for this section
case .sectionWithOrthogonalScrollingBehaviour:
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(1.0*9.0/16.0))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
group.interItemSpacing = .fixed(0) // should (probably) be 0 otherwise there is an offset when scrollingToIndex
section.interGroupSpacing = 0 // should (probably) be 0 otherwise there is an offset when scrollingToIndex
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 0, bottom: 0, trailing: 0) // leading and trailing should (certainly) be 0 otherwise the pages are offsetted in relation to the view
section.orthogonalScrollingBehavior = .continuous // should be continous, otherwise it won't work
return section
}
}
return layout
}
collectionView.collectionViewLayout = createLayout()
}
为了以编程方式滚动,我实现了一个分段控件。当用户点击一个片段时,正交滚动部分会自动滚动到与所选片段对应的单元格。
@IBAction func segmentedControlValueChanged(_ sender: UISegmentedControl) {
// determine which Item belongs to the selected segment. In my case Items in a Section are represented by an enum called 'Item'
let dataSourceIndexPath = self.dataSource.indexPath(for: .itemCase)
let pressentationIndexPath = self.collectionView.presentationIndexPath(forDataSourceIndexPath: dataSourceIndexPath)! // This step is necessary, otherwise the next line does not have have wanted behaviour (I'm force unwrapping here to simplify. Don't do that in your final code)
self.collectionView.scrollToItem(at: pressentationIndexPath, at: .centeredHorizontally, animated: true) // make sure you use .centeredHorizontally
}
我不确定这是 Apple 打算如何使用它。它可能会在下一个 Xcode beta 版本中再次刹车。
旁注:如果您想知道为什么我需要/想要一个分段控件来滚动集合视图:这是因为正交滚动部分中的单元格内容需要消耗水平平移手势(单元格都是您可以移动的图表您的手指沿着,然后在触摸的位置显示图表值)。是的......我知道这也可以通过其他方式完成,但我想使用组合布局,因为它与其他部分很好地结合在一起,并且我想保持正交滚动行为的这种甜蜜的内置动画(即使这个现在部分丢失了,因为正交滚动行为需要 .continues 才能工作),我只是想看看它是否可以完成 :)