如何让SwiftUI WebView实现动态加载URL的功能?
问题解决方法
问题根源
- WebView的
url属性错误使用了@State修饰:@State仅用于视图内部私有状态的管理,外部传入的初始值仅会在视图首次初始化时生效,后续外部对该属性的修改既不会同步到WebView内部,也无法触发updateUIView方法执行。 - ContentView中提前创建了WebView实例作为普通属性:在按钮动作中修改该实例的
url不会触发ContentView的body重绘,修改不会生效,渲染到视图树中的WebView还是最初的实例。
修复步骤
- 调整WebView的属性定义,移除
@State修饰,直接用普通常量接收传入的url:
struct WebView : UIViewRepresentable { let url: String // 移除@State,改为接收外部传入的常量 func makeUIView(context: Context) -> WKWebView { return WKWebView() } func updateUIView(_ uiView: WKWebView, context: Context) { uiView.load(url) } }
- 调整ContentView的逻辑,不提前创建WebView实例,改为持有
@State修饰的url变量,在需要渲染WebView时动态传入:
struct ContentView: View { @State private var showLoginForm: Bool = true // 新增@State修饰的url变量,用来控制WebView加载的地址 @State private var webUrl = "https://www.google.com" var body: some View { if showLoginForm { Button(action: { showLoginForm = false // 直接修改@State修饰的webUrl即可触发视图重绘 webUrl = "https://www.example.com/go/1" }) { Text("跳转页面") } } else { // 渲染时动态传入最新的webUrl WebView(url: webUrl) } } }
原理解释
当@State修饰的webUrl发生变化时,会触发ContentView的body重新计算,渲染WebView时会传入最新的url,进而触发WebView的updateUIView方法执行,调用load方法加载新地址。
内容的提问来源于stack exchange,提问作者fferri
相关产品推荐
相关产品推荐

