1

我正在使用 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)方法上工作,但我不知道如何实现这个逻辑。或者也许所有的概念都是错误的?

这是我的网络视图

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

4

1 回答 1

0

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

func updateUIView(_ uiView: WKWebView, context: Context) {
    guard let url = URL(string: query) else { return }
    if uiView.url == nil || uiView.url?.absoluteString.trimmingCharacters(in: CharacterSet(arrayLiteral: "/")) != query {
        let request = URLRequest(url: url)
        uiView.load(request)
    }
}
于 2020-09-22T21:48:05.763 回答