UICollectionViewCompositionalLayout设置contentOffset。

6

我一直想知道,使用 CompositionalLayout 设置集合视图的 contentOffset 的当前方式(如果有的话)是什么。 我明白 CompositionalLayout 构建了不同的部分,并且每个部分都有自己的嵌套滚动视图,这就是为什么我们必须使用 visibleItemsInvalidationHandler 来获取 contentOffset 而不是传统的 scrollViewDidScroll(_scrollView: UIScrollView) 代理。 但是,我似乎找不到任何用于将 contentOffset 设置回集合视图(部分或整个组合)的API。

更具体的例子,假设我们有一个集合视图和一个滚动视图,我希望在它们之间同步垂直滚动:

集合视图:

private lazy var collectionView: UICollectionView = {
        let collectionViewLayout = createCompositionalLayout()
        return UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
    }()

布局:

    private func createCompositionalLayout() -> UICollectionViewLayout {
        let layout = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
            let sectionIdentifier = self.dataSource.snapshot().sectionIdentifiers[sectionIndex]
            let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(self.view.height))
            let item = NSCollectionLayoutItem(layoutSize: itemSize)
            let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
            let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
            let section = NSCollectionLayoutSection(group: group)
            
            return section
        }
        
        if let collectionHeader = createHeaderSupplementaryItem() {
            let layoutConfiguration = UICollectionViewCompositionalLayoutConfiguration()
            layoutConfiguration.boundarySupplementaryItems = [collectionHeader]
            layout.configuration = layoutConfiguration
        }

        return layout
    }

使用流式布局时,我会使用UIScrollViewDelegate来获得所需的行为:

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard self.scrollView == scrollView else {
            return
        }

        collectionView.contentOffset.y = scrollView.contentOffset.y
    }

但是在组合布局中会造成混乱。
那么在组合布局上实现相同的行为是否可能呢?
顺便说一句,显然我为了举例子简化了我的代码,我的集合更加复杂,很难转换到流式布局。

1个回答

1

我没有找到官方API,所以我手动查找内部ScrollView,并滚动它。

我创建了这个UICollectionView扩展。

func getScrollViewFromCompositionLayout(section: Int) -> UIScrollView? {
    return subviews
        .compactMap { $0 as? UIScrollView }
        .first(where: { scrollView in
            guard let cell = scrollView.subviews.first as? UICollectionViewCell else {
                return false
            }

            return indexPath(for: cell)?.section == section
        })
}

目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community
这是我找到的最接近的解决方案,如果您能通过代码解释并提供更多信息,我将不胜感激。 - Didami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接