Reputation: 1818
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).
I am developing the application in Swift.
What is the best method to do this?
Upvotes: 17
Views: 27493
Reputation: 457
According to recommendations in apple docs
Also UIWebView is deprecated after 12 iOS
Here is solution using Swift 5.3 and WKWebiew
First replace your UIWebview with WKWebview
Then conform to WKNavigationDelegate and implement method
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 = self
Upvotes: 8
Reputation: 4945
Updated for 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
}
Upvotes: 1
Reputation: 4468
This is done essentially the same way in Swift as in Obj-C:
First, declare that your view controller conforms to UIWebViewDelegate
class MyViewController: UIWebViewDelegate
Then implement webViewShouldStartLoadingWithRequest:navigationType:
in your View Controller:
// 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, e.g., in viewDidLoad
or in your Storyboard:
webView.delegate = self
Upvotes: 48
Reputation: 81
Updated for 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
}
Upvotes: 7
Reputation: 2121
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. If you send those off to the OS with [[UIApplication sharedApplication]openURL:]
they will open in Safari.
Upvotes: 3