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

SwiftUI如何在子视图中调用父ScrollViewReader的scrollTo方法

实现方案

有两种常用的无侵入实现方式,均可正常运行:

方案1:直接传递ScrollViewProxy到子视图

直接把父视图ScrollViewReader生成的proxy实例作为参数传给子视图,适合子视图滚动逻辑固定的场景。

子视图实现:

import SwiftUI

struct ChildButton: View {
    // 声明接收ScrollViewProxy类型参数
    let scrollProxy: ScrollViewProxy
    
    var body: some View {
        Button("go to bottom") {
            scrollProxy.scrollTo(19)
        }
    }
}

父视图修改:

只需要在初始化子视图时传入proxy即可:

import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollViewReader { value in
            ScrollView {
                // 传入当前ScrollView的proxy实例
                ChildButton(scrollProxy: value)
                ForEach(0..<20) { i in
                    Text("\(i)")
                        .frame(width: 200, height: 200)
                        .id(i)
                }
            }
        }
    }
}

方案2:使用闭包回调实现

滚动逻辑完全放在父视图处理,子视图只负责触发点击事件,耦合度更低,适合子视图多场景复用的情况。

子视图实现:

import SwiftUI

struct ChildButton: View {
    // 声明点击回调闭包
    var onTap: () -> Void
    
    var body: some View {
        Button("go to bottom") {
            onTap()
        }
    }
}

父视图修改:

初始化子视图时实现滚动逻辑的闭包即可:

import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollViewReader { value in
            ScrollView {
                ChildButton {
                    value.scrollTo(19)
                }
                ForEach(0..<20) { i in
                    Text("\(i)")
                        .frame(width: 200, height: 200)
                        .id(i)
                }
            }
        }
    }
}

选型建议

  • 子视图仅用于当前ScrollView场景、滚动位置固定:选方案1,代码更简洁
  • 子视图需要在多个ScrollView下复用、滚动位置需要父视图动态计算:选方案2,可维护性更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:00:01