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

Swift中如何访问WKWebView结构体内部Coordinator类的IsLoading属性

解决SwiftUI中访问WKWebView Coordinator加载状态的问题

直接给你可行的方案,核心是让Coordinator和封装的WebView结构体建立关联,把加载状态同步到结构体的可监听属性上,这样外部就能轻松获取状态,同时在加载完成时直接执行JavaScript。

步骤1:封装WKWebView时同步加载状态

在你的UIViewRepresentable结构体里定义可监听的加载状态属性,然后在Coordinator中更新这个属性:

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    let url: URL
    // 定义@Published属性,外部可监听加载状态
    @Published var isLoading = false
    
    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.navigationDelegate = context.coordinator
        webView.load(URLRequest(url: url))
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        // 初始化Coordinator时传入当前WebView实例
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: WebView
        
        init(parent: WebView) {
            self.parent = parent
        }
        
        // 网页开始加载时标记状态
        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            parent.isLoading = true
        }
        
        // 网页加载完成时更新状态,并执行JavaScript
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            parent.isLoading = false
            // 这里写你要执行的JS代码
            webView.evaluateJavaScript("document.body.style.backgroundColor = '#f0f0f0'") { result, error in
                if let error = error {
                    print("JS执行出错:\(error.localizedDescription)")
                } else {
                    print("JS执行成功,返回值:\(result ?? "无返回值")")
                }
            }
        }
        
        // 加载失败也要更新状态,避免一直显示加载中
        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            parent.isLoading = false
        }
    }
}

步骤2:在SwiftUI视图中使用并监听状态

把WebView实例用@StateObject持有,这样能监听isLoading的变化:

struct ContentView: View {
    @StateObject private var webView = WebView(url: URL(string: "https://example.com")!)
    
    var body: some View {
        VStack {
            // 根据加载状态显示提示
            if webView.isLoading {
                Text("网页加载中...")
                    .padding()
            }
            WebView(url: URL(string: "https://example.com")!)
                .edgesIgnoringSafeArea(.all)
        }
    }
}

额外说明

  • 如果需要让外部视图控制加载状态,也可以把@Published var isLoading换成@Binding var isLoading,这样外部传入@State变量就能双向绑定状态。
  • 加载完成时的JavaScript直接在Coordinator的didFinish方法里执行是最稳妥的,因为这个回调就是网页完全加载完成的时机,不需要额外判断状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:42:33