在SwiftUI中使用WKWebView时,如何拦截链接导航



我在SwiftUI应用程序中使用WKWebView。我的捆绑包中有一个HTML文件,我最初将其加载到WKWebView中。文件中有一个链接,如果点击,我想在外部浏览器中打开。我使用以下代码创建了WKWebView:

import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
typealias UIViewType = WKWebView
let request: URLRequest
func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
let webView = WKWebView()
let delegate = WVNavigationDelegate()
webView.navigationDelegate = delegate
return webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
uiView.load(request)
}
}

我使用以下代码创建了代理:

import Foundation
import WebKit
class WVNavigationDelegate: NSObject, WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
switch navigationAction.navigationType {
case WKNavigationType.linkActivated:
UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
decisionHandler(.cancel)
default:
decisionHandler(.allow)
}
}
}

如果我注释掉创建和分配代理的行,除了从外部打开的链接外,一切都很好。在中编译了这些行之后,WebView中就不会加载任何内容。我在委托中的函数开头放了一个print()语句,它甚至没有被执行。我在这里做错了什么?

navigationDelegate很弱,因此在提供的代码中,一旦从makeUIView退出,就会释放它。

解决方案是将其保留为成员,如

struct WebView: UIViewRepresentable {
typealias UIViewType = WKWebView
let request: URLRequest
private let delegate = WVNavigationDelegate()   // << here !!
func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = delegate
return webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
uiView.load(request)
}
}

最新更新