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

SwiftUI中WKWebView点击返回加载延迟,如何获取加载进度并展示?

实现方案

我们可以通过KVO监听WKWebView自带的estimatedProgress属性获取加载进度,结合@Binding把进度同步到SwiftUI层驱动进度条展示,不管是返回、前进还是首次加载场景都可以自动获取进度,完整修改如下:


1. 修改WebViewForCommunityTab结构体

新增进度绑定属性、KVO监听逻辑和导航代理处理:

import SwiftUI
import WebKit
import Combine // 监听属性需要用到该库

struct WebViewForCommunityTab : UIViewRepresentable {
    let request: URLRequest
    var webview: WKWebView?
    // 新增绑定属性,用于把加载进度同步到上层View
    @Binding var loadProgress: Double
    // 存储KVO监听实例
    private var progressObserver: NSKeyValueObservation?

    init(web: WKWebView?, req: URLRequest, loadProgress: Binding<Double>) {
        self.webview = WKWebView()
        self.request = req
        self._loadProgress = loadProgress
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> WKWebView  {
        webview?.navigationDelegate = context.coordinator
        // 监听WKWebView的加载进度属性
        progressObserver = webview?.observe(\.estimatedProgress, options: [.new]) { _, value in
            DispatchQueue.main.async {
                self.loadProgress = value.newValue ?? 0
            }
        }
        return webview!
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }

    func goBack(){
        webview?.goBack()
    }

    func goForward(){
        webview?.goForward()
    }

    func goHomeScreen(){
        webview?.load(URLRequest(url: (URL(string: DefaultUrlString.CommunityWebLink)!)))
    }

    // 新增Coordinator处理WKWebView导航代理事件
    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebViewForCommunityTab

        init(_ parent: WebViewForCommunityTab) {
            self.parent = parent
        }

        // 页面加载完成后重置进度,隐藏进度条
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            DispatchQueue.main.async {
                self.parent.loadProgress = 0
            }
        }

        // 页面加载失败也重置进度
        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            DispatchQueue.main.async {
                self.parent.loadProgress = 0
            }
        }
    }
}

2. 修改WebContentView添加进度条展示

新增状态变量存储加载进度,在WebView顶部插入进度条:

struct WebContentView: View {
    // 存储加载进度的状态变量,取值范围0~1
    @State private var loadProgress: Double = 0
    // 初始化WebView时传入进度绑定
    let webview = WebViewForCommunityTab(web: nil, req: URLRequest(url: URL(string: DefaultUrlString)!), loadProgress: $loadProgress)

    var body: some View {
        ZStack {
            VStack(spacing: 0) {
                // 仅加载过程中显示进度条
                if loadProgress > 0 && loadProgress < 1 {
                    ProgressView(value: loadProgress, total: 1)
                        .progressViewStyle(LinearProgressViewStyle(tint: .blue))
                        .frame(height: 2)
                }
                webview
                HStack (alignment: .center) {
                    Group {
                        Spacer()
                        CustomButtonForWebView(btnImageTitle: ArrowLeftCircleImg, action: {
                            self.webview.goBack()
                        })
                        CustomButtonForWebView(btnImageTitle: ArrowRightCircleImg, action: {
                            self.webview.goForward()
                        })
                        Spacer()
                    }.padding(.bottom,10)
                }.frame(width: UIScreen.main.bounds.width, height: 40, alignment: .center)
            }.hiddenNavigationBarStyle().background(Color.white)
        }
    }
}

逻辑说明

  • WKWebView的estimatedProgress是系统维护的0~1之间的浮点数,代表当前页面的加载进度,返回、前进、刷新、首次加载等所有页面跳转场景都会自动更新该值
  • 通过KVO监听该属性,把进度值同步到SwiftUI的状态变量,即可驱动进度条实时更新
  • 页面加载完成/失败后重置进度为0,进度条会自动隐藏

内容的提问来源于stack exchange,提问作者Sham Dhiman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:15:06