0

我正在实施UICollectionViewCompositionalLayout和使用

section.orthogonalScrollingBehavior = .groupPagingCentered

水平滚动一个部分。

这允许用户在一个部分中从一个页面水平滚动到另一个页面。

我用

section.visibleItemsInvalidationHandler = {...}

获取用户滚动到的页面。

如何以编程方式滚动到本节中的页面?

4

1 回答 1

0

我真的让它工作了。此代码适用于 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 才能工作),我只是想看看它是否可以完成 :)

于 2020-07-15T00:46:29.873 回答