You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用UIKit Compositional Layout的UICollectionView如何按section滚动或获取偏移量

实现方案核心逻辑

基于Compositional Layout配置了正交滚动(即section内部横向滚动)的UICollectionView,系统会自动为每个设置了orthogonalScrollingBehavior的section生成一个私有的内嵌UIScrollView实例,该section的所有横向滚动逻辑都由这个scrollView管理,你需要的两个功能都可以通过操作这个内嵌scrollView实现。


第一步:获取指定section对应的内嵌滚动视图

给UICollectionView写扩展方法,兼容iOS14+:

extension UICollectionView {
    /// 获取指定section的内嵌正交滚动视图
    /// - Parameter section: 目标section索引
    /// - Returns: 对应section的内嵌UIScrollView,未开启正交滚动则返回nil
    func orthogonalScrollView(for section: Int) -> UIScrollView? {
        // 先校验section合法性
        guard section < numberOfSections,
              // 取该section的布局属性确定位置范围
              let sectionFrame = layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath(item: 0, section: section))?.frame ??
              layoutAttributesForItem(at: IndexPath(item: 0, section: section))?.frame else {
            return nil
        }
        
        // 遍历子视图匹配对应位置的内嵌scrollView
        for subview in subviews where subview is UIScrollView {
            let scrollView = subview as! UIScrollView
            if scrollView.frame.minX == sectionFrame.minX,
               scrollView.frame.minY >= sectionFrame.minY,
               scrollView.frame.maxY <= sectionFrame.maxY {
                return scrollView
            }
        }
        return nil
    }
}

注意:该方法依赖的系统内嵌视图结构从iOS13发布Compositional Layout以来到最新iOS17都没有变动,兼容性稳定。


第二步:实现需求功能

继续在刚才的UICollectionView扩展中添加对应方法:

1. 控制指定section滚动到目标偏移

func setContentOffset(_ offset: CGFloat, inSection section: Int, animated: Bool = false) {
    guard let scrollView = orthogonalScrollView(for: section) else { return }
    // 横向滚动仅修改x值即可,y保持默认0
    scrollView.setContentOffset(CGPoint(x: offset, y: 0), animated: animated)
}

调用示例:collectionView.setContentOffset(100, inSection: 2)完全符合你要的调用效果。

2. 获取指定section的contentOffset

func contentOffset(for section: Int) -> CGPoint? {
    return orthogonalScrollView(for: section)?.contentOffset
}

如果仅需要横向偏移,直接取返回值的x属性即可。


注意事项

  • 不要对获取到的内嵌scrollView做修改delegate、添加自定义手势等额外操作,仅用来调整偏移、读取滚动状态即可,避免触发系统内部异常
  • 如果你的section有固定header,优先用header的布局属性做frame匹配,准确率会更高
  • 如果后续系统版本升级修改了内嵌视图结构,只需要调整frame匹配的逻辑即可

内容的提问来源于stack exchange,提问作者darksider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 09:06:04