How do I intercept link navigation when using WKWebView in SwiftUI?

不羁的心 提交于 2021-01-01 07:53:38

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!