问题
I'm using WKWebView in a SwiftUI app. I have an HTML file in my bundle that I'm initially loading into the WKWebView. The file has a link in it that I would like to open in an external browser if tapped. I've created the WKWebView using the following code:
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)
}
}
I've created the delegate using this code:
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)
}
}
}
If I comment out the lines creating and assigning the delegate, everything works fine with the exception of links opening externally. With those lines compiled in, nothing loads in the WebView. I put a print() statement at the beginning of the function in the delegate and it didn't even get executed. What am I doing wrong here?
回答1:
The navigationDelegate is weak so in the provided code it is released as soon as exit from makeUIView.
The solution is to keep it as member, as in
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)
}
}
来源:https://stackoverflow.com/questions/61650296/how-do-i-intercept-link-navigation-when-using-wkwebview-in-swiftui