You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SwiftUI中如何实现点击按钮打开WebView

解决SwiftUI点击按钮打开WebView无响应的问题

你遇到的问题是典型的SwiftUI声明式UI理解误区——在Buttonaction闭包里直接初始化Webview结构体并不会让这个视图显示出来,因为SwiftUI是通过声明式描述视图状态来渲染界面的,而非命令式地创建视图实例。

解决方案1:使用sheet模态弹窗展示WebView

这是最直接的实现方式,通过状态变量控制弹窗的显示与隐藏:

  1. ContentView中添加@State变量管理WebView的显示状态
  2. 修改按钮的action逻辑,仅切换状态变量的值
  3. ContentView添加.sheet修饰符,绑定状态变量并声明Webview

修改后的ContentView代码如下:

struct ContentView: View {
    // 控制WebView弹窗的显示状态
    @State private var shouldShowWebView = false
    
    var body: some View {
        Button(action: {
            // 点击按钮切换状态,触发sheet展示
            shouldShowWebView = true
        }) {
            Image("go")
        }
        // 绑定状态变量,状态为true时展示WebView
        .sheet(isPresented: $shouldShowWebView) {
            Webview(url: URL(string:"https://www.google.com")!)
        }
    }
}

解决方案2:使用导航栈跳转(iOS 16+)

如果希望通过导航栈的方式打开WebView(比如从导航栏进入),可以使用NavigationStack

struct ContentView: View {
    @State private var navigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            Button(action: {
                // 将目标URL加入导航路径
                navigationPath.append(URL(string:"https://www.google.com")!)
            }) {
                Image("go")
            }
            // 定义导航路径对应的视图
            .navigationDestination(for: URL.self) { url in
                Webview(url: url)
            }
        }
    }
}

原代码不生效的原因

SwiftUI的视图渲染依赖状态变化驱动的视图树更新。你原本在action里只是创建了Webview实例,但这个实例并没有被加入当前视图树,所以SwiftUI不会渲染它。而把Webview实例写在body里时,它会成为视图树的一部分,因此会自动显示。

你的WebviewWebviewController实现是没问题的,只需调整视图的展示方式即可。

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

火山引擎 最新活动