如何强制在 WebView 中单击的任何链接在 Safari 中打开?
How can I force any links clicked within a WebView to open in Safari?
我的应用程序中有一个 WebView,我希望在 WebView 中单击的所有链接都能在 Safari 中打开(而不是 WebView 本身)。
我正在 Swift 开发应用程序。
最好的方法是什么?
您需要在您的 Web 视图的委托上实现方法 webViewShouldStartLoadingWithRequest:navigationType
并查找要在 Safari 中打开的链接。如果您使用 [[UIApplication sharedApplication]openURL:]
将它们发送到 OS,它们将在 Safari 中打开。
这在 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
更新 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
}
更新为 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
}
根据苹果文档中的建议
此外 UIWebView 在 12 之后被弃用 iOS
这是使用 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
我的应用程序中有一个 WebView,我希望在 WebView 中单击的所有链接都能在 Safari 中打开(而不是 WebView 本身)。
我正在 Swift 开发应用程序。
最好的方法是什么?
您需要在您的 Web 视图的委托上实现方法 webViewShouldStartLoadingWithRequest:navigationType
并查找要在 Safari 中打开的链接。如果您使用 [[UIApplication sharedApplication]openURL:]
将它们发送到 OS,它们将在 Safari 中打开。
这在 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
更新 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
}
更新为 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
}
根据苹果文档中的建议
此外 UIWebView 在 12 之后被弃用 iOS
这是使用 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