首页 > 解决方案 > WKWebView: Use same delegate code (WKNavigationDelegate) in multiple view controllers

问题描述

I have an application with 5 navigation tabs, each one with a different View Controller that has a WKWebView inside it. I would like to somehow use the same delegate code to prevent copy and pasting in each one.

How do I reuse the "decidePolicyFor" code in different View Controllers?

class DashboardViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    var webView: WKWebView!

    override func loadView() {
        let webConfiguration = WebViewUtils.getWKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.load(Constants.DASHBOARD)
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        if navigationAction.request.url?.scheme == "tel" {
            UIApplication.shared.open(navigationAction.request.url!, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
            decisionHandler(.cancel)
        }
        else {
            decisionHandler(.allow)
        }
    }
}

标签: iosswiftxcode

解决方案


您可以在这样的对象中提取导航委托代码:

class MyWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if navigationAction.request.url?.scheme == "tel" {
            UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
        } else {
            decisionHandler(.allow)
        }
    }
}

然后在整个应用程序中使用此对象的实例:

class DashboardViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    var webView: WKWebView!
    let webViewNavigationDelegate = MyWebViewNavigationDelegate()

    override func loadView() {
        let webConfiguration = WebViewUtils.getWKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = webViewNavigationDelegate
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.load(Constants.DASHBOARD)
    }
}

推荐阅读