WKWebView:在多个视图控制器中使用相同的委托代码(WKNavigationDelegate)

时间:2019-04-29 15:23:22

标签: ios swift xcode

我有一个带有5个导航选项卡的应用程序,每个选项卡都有一个不同的View Controller,其中包含WKWebView。我想以某种方式使用相同的委托代码来防止复制和粘贴每个代码。

如何在不同的View Controller中重用“ decidePolicyFor”代码?

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)
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您可以像这样通过dependency injection来实现:

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

class DashboardViewController: UIViewController, WKUIDelegate {

    lazy var webView: WKWebView = {
        let webConfiguration = WKWebViewConfiguration()
        return WKWebView(frame: .zero, configuration: webConfiguration)
    }()

    let navigationDelegate: WKNavigationDelegate
    init(navigationDelegate: WKNavigationDelegate) {
        self.navigationDelegate = navigationDelegate
        super.init(nibName: nil, bundle: nil)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        webView.uiDelegate = self
        webView.navigationDelegate = navigationDelegate
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.load(Constants.DASHBOARD)
    }

}

let delegate = NavigationBehavior()
let vc1 = DashboardViewController(navigationDelegate: delegate)
let vc2 = ProfileViewController(navigationDelegate: delegate)

答案 1 :(得分:0)

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

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)
    }
}