UICollectionViewCompositionalLayout设置section.orthogonalScrollingBehavior页面以编程方式进行?

时间:2020-05-18 18:43:27

标签: ios swift uicollectionview uicollectionviewcompositionallayout

我正在实现UICollectionViewCompositionalLayout并使用

section.orthogonalScrollingBehavior = .groupPagingCentered

水平滚动部分。

这使用户可以在一个部分中水平滚动页面。

我使用

section.visibleItemsInvalidationHandler = {...}

获取用户滚动到的页面。

如何以编程方式滚动到此部分中的页面?

1 个答案:

答案 0 :(得分:0)

我实际上使它正常工作。该代码适用于XCode 12 Beta 2 /目标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才能正常工作),我只是想看看它是否可以完成:)