【问题标题】:How can I force any links clicked within a WebView to open in Safari?如何强制在 WebView 中单击的任何链接在 Safari 中打开?
【发布时间】:2015-02-18 01:15:34
【问题描述】:

我的应用程序中有一个 WebView,我希望在 WebView 中单击的任何链接都可以在 Safari 中打开(而不是 WebView 本身)。

我正在用 Swift 开发应用程序。

最好的方法是什么?

【问题讨论】:

    标签: ios xcode swift hyperlink webview


    【解决方案1】:

    这在 Swift 中的完成方式与在 Obj-C 中的方式基本相同:

    首先,声明你的视图控制器符合UIWebViewDelegate

    class MyViewController: UIWebViewDelegate
    

    然后在你的视图控制器中实现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
        }
    }
    

    最后,设置 UIWebView 的委托,例如,在 viewDidLoad 或 Storyboard 中:

    webView.delegate = self
    

    【讨论】:

    • 好的。我唯一不明白的是class MyViewController: UIWebViewDelegate。我该怎么办?谢谢
    • 在 Swift 中,您可以通过在类名 (see docs) 之后添加协议名称来声明您的类符合协议。在您的情况下,它可能看起来像 class MyViewController: UIViewController, UIWebViewDelegate { ...stuff in the class... }
    • 谢谢@RonaldMartin,它很有魅力,非常感谢
    • 如何用WebKit实现同样的效果?
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      根据苹果文档中的建议

      iOS 12 之后 UIWebView 也被弃用

      这是使用 Swift 5.3 和 WKWebiew 的解决方案

      首先用 WKWebview 替换你的 UIWebview

      然后符合WKNavigationDelegate并实现方法

      这里是代码

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

      然后为您的 wkWebView 设置“navigationDelegate”

      wkWebView.navigationDelegate = self
      

      【讨论】:

      • 如果您加载本地 html 文件,请在 gurad 中添加:UIApplication.shared.canOpenURL(url)
      【解决方案4】:

      您需要在 Web 视图的委托上实现方法 webViewShouldStartLoadingWithRequest:navigationType 并查找要在 Safari 中打开的链接。如果您使用[[UIApplication sharedApplication]openURL:] 将它们发送到操作系统,它们将在 Safari 中打开。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2013-01-10
          • 1970-01-01
          • 1970-01-01
          • 2018-04-13
          • 1970-01-01
          • 1970-01-01
          • 2013-01-07
          • 1970-01-01
          相关资源
          最近更新 更多