#5 ScrollViewReader

38 阅读1分钟

功能

ScrollViewReader 不是滚动容器,而是 只负责“滚动导航” 的视图包装器。它生成一个 proxy,供内部代码调用 scrollTo(id, anchor:) 将任意子项瞬间或动画地滚动到可见区域。

核心 API

proxy.scrollTo<ID>(
    id,           // 与子项 .id 同类型
    anchor: .top  // 可选,目标对齐位置
)
  • 不返回任何值;若 id 不存在静默忽略。
  • 必须包在 withAnimation 内才能产生平滑滚动。

示例

struct ScrollViewReaderBootcamp: View {
    
    var body: some View {
        ScrollViewReader { proxy in
            ScrollView {
                Button("Scroll to Bottom") {
                    withAnimation {
                        proxy.scrollTo(bottomID)
                    }
                }
                .id(topID)


                VStack(spacing: 0) {
                    ForEach(0..<100) { i in
                        color(fraction: Double(i) / 100)
                            .frame(height: 32)
                    }
                }


                Button("Top") {
                    withAnimation {
                        proxy.scrollTo(topID)
                    }
                }
                .id(bottomID)
            }
        }
    }
}

与 ScrollView 的关系

  • ScrollViewReader 自身不滚动、不占位,仅提供控制句柄。
  • 一个 Reader 可包裹多个 ScrollView / List;每个 ScrollView 内部子项 id 唯一即可。
  • 支持横向滚动:使用 ScrollView(.horizontal) 即可,API 不变。

注意事项

  1. scrollTo 必须在 Reader 的闭包内调用,否则编译错误。
  2. 若 id 重复或缺失,滚动无效果且不报错,请保证数据范围正确。
  3. 键盘弹出、屏幕旋转等场景,可结合 GeometryReader 动态计算锚点,避免遮挡。