在 SwiftUI 中使用 WKWebView 时如何拦截链接导航? [英] How do I intercept link navigation when using WKWebView in SwiftUI?
问题描述
我在 SwiftUI 应用中使用 WKWebView.我的包中有一个 HTML 文件,我最初将它加载到 WKWebView 中.该文件中有一个链接,如果点击,我想在外部浏览器中打开该链接.我使用以下代码创建了 WKWebView:
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)
}
}
}
如果我注释掉创建和分配委托的行,除了在外部打开的链接外,一切正常.编译这些行后,WebView 中不会加载任何内容.我在委托中的函数开头放置了一个 print()
语句,它甚至没有被执行.我在这里做错了什么?
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?
推荐答案
navigationDelegate
很弱,所以在提供的代码中它会在从 makeUIView
退出时立即释放.
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)
}
}
这篇关于在 SwiftUI 中使用 WKWebView 时如何拦截链接导航?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!