简体   繁体   English

如何强制在 WebView 中单击的任何链接在 Safari 中打开?

[英]How can I force any links clicked within a WebView to open in Safari?

I have a WebView in my application and I would like any links clicked within the WebView to open in Safari (instead of the WebView itself).我的应用程序中有一个 WebView,我希望在 WebView 中单击的任何链接在 Safari 中打开(而不是 WebView 本身)。

I am developing the application in Swift.我正在 Swift 中开发应用程序。

What is the best method to do this?执行此操作的最佳方法是什么?

This is done essentially the same way in Swift as in Obj-C:这在 Swift 中的完成方式与 Obj-C 中的基本相同:

First, declare that your view controller conforms to UIWebViewDelegate首先,声明你的视图控制器符合UIWebViewDelegate

class MyViewController: UIWebViewDelegate

Then implement webViewShouldStartLoadingWithRequest:navigationType: in your View Controller:然后在你的视图控制器中实现webViewShouldStartLoadingWithRequest:navigationType:

// Swift 1 & 2
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    switch navigationType {
    case .LinkClicked:
        // Open links in Safari
        UIApplication.sharedApplication().openURL(request.URL)
        return false
    default:
        // Handle other navigation types...
        return true
    }
}

// Swift 3
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    switch navigationType {
    case .linkClicked:
        // Open links in Safari
        guard let url = request.url else { return true }

        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            // openURL(_:) is deprecated in iOS 10+.
            UIApplication.shared.openURL(url)
        }
        return false
    default:
        // Handle other navigation types...
        return true
    }
}

Finally, set your UIWebView 's delegate, eg, in viewDidLoad or in your Storyboard:最后,设置您的UIWebView的委托,例如,在viewDidLoad或您的 Storyboard 中:

webView.delegate = self

Updated for swift 3为 swift 3 更新

func webView(_: UIWebView, shouldStartLoadWith: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == UIWebViewNavigationType.linkClicked {
        UIApplication.shared.open(shouldStartLoadWith.url!, options: [:], completionHandler: nil)
        return false
    }
    return true
}

According to recommendations in apple docs根据苹果文档中的建议

在此处输入图片说明

Also UIWebView is deprecated after 12 iOS UIWebView 在 iOS 12 之后也被弃用

Here is solution using Swift 5.3 and WKWebiew这是使用 Swift 5.3 和 WKWebiew 的解决方案

First replace your UIWebview with WKWebview首先用 WKWebview 替换你的 UIWebview

Then conform to WKNavigationDelegate and implement method然后符合WKNavigationDelegate并实现方法

在此处输入图片说明

Here is code这是代码

extension WebViewControllerImpl: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard case .linkActivated = navigationAction.navigationType,
              let url = navigationAction.request.url
        else {
            decisionHandler(.allow)
            return
        }
        decisionHandler(.cancel)
        UIApplication.shared.openURL(url)
   }
}

Then set 'navigationDelegate' for your wkWebView然后为您的 wkWebView 设置“navigationDelegate”

wkWebView.navigationDelegate = self

You need to implement the method webViewShouldStartLoadingWithRequest:navigationType on your web view's delegate and look for the links you want to open in Safari.您需要在 Web 视图的委托上实现方法webViewShouldStartLoadingWithRequest:navigationType并查找要在 Safari 中打开的链接。 If you send those off to the OS with [[UIApplication sharedApplication]openURL:] they will open in Safari.如果您使用[[UIApplication sharedApplication]openURL:]将它们发送到操作系统,它们将在 Safari 中打开。

Updated for swift 4.2为 swift 4.2 更新

func webView(_: UIWebView, shouldStartLoadWith: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
    if navigationType == UIWebView.NavigationType.linkClicked {
        UIApplication.shared.open(shouldStartLoadWith.url!, options: [:], completionHandler: nil)
        return false
    }
    return true
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM