如何在SwiftUI中观察WKWebView的加载进度?

问题描述

我正在使用SwiftUI构建Web浏览器,并将视图分为3部分:SearchView,WebView(UIViewRepresentable)。

在SearchView中,我有@Binding var query,它在TextField的onCommit方法上进行了更新。 WebView具有@Binding var query@Binding var loadingProgress。正确知道当查询和进度都更新时,webView也会更新。如何过滤这些事件,并且不重新加载webView以进行进度更改?

我想我需要使用updateUIView(_ uiView: WKWebView,context: Context)方法,但是我不知道如何实现此逻辑。还是所有的概念都是错误的?

这是我的WebView

struct browserWebView: UIViewRepresentable {
    
var webView = WKWebView()

@Binding var query: String
@Binding var loadingProgress: Float

func makeUIView(context: Context) -> WKWebView {
    context.coordinator.addProgressObserver()
    webView.navigationDelegate = context.coordinator
    return webView
}

func updateUIView(_ uiView: WKWebView,context: Context) {
    loadQuery()
}

private func loadQuery() {
    guard let url = URL(string: query) else { return }
    let request = URLRequest(url: url)
    webView.load(request)
}

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

class Coordinator: NSObject,WKNavigationDelegate {
    var parent: browserWebView
    
    init(_ parent: browserWebView) {
        self.parent = parent
    }
    
    func addProgressObserver() {
        parent.webView.addobserver(self,forKeyPath: #keyPath(WKWebView.estimatedProgress),options: .new,context: nil)
    }
    
    override func observeValue(forKeyPath keyPath: String?,of object: Any?,change: [NSkeyvalueChangeKey : Any]?,context: UnsafeMutableRawPointer?) {
        if let o = object as? WKWebView,o == parent.webView {
            if keyPath == #keyPath(WKWebView.estimatedProgress) {
                parent.loadingProgress = Float(parent.webView.estimatedProgress)
            }
        }
    }
  }
}

我在外部拥有@State属性,该属性可更新ProgressView

解决方法

您可以简单地将网络视图的当前url字符串与查询进行比较,以跳过重新加载操作,例如:

arrayToList