There is a social link button inside WKWebView. When I click on the button nothing happens.
Could you please tell me how to open the link by clicking on the button?
Thanks in advance.
what link u want to open change "facebook","twitter" and you can add more links also
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url ,UIApplication.shared.canOpenURL(url) {
// let urlString = try! String(contentsOf: url)
if (url.absoluteString.range(of: "facebook.com") != nil || url.absoluteString.range(of: "twitter.com") != nil){
//UIApplication.shared.open(url)
print("Redirected to browser. No need to open it locally")
decisionHandler(.cancel)
}else{
print("Open it locally")
decisionHandler(.allow)
}
}
You need a on click listener.
You can use WKWebView to display interactive web content in your app. Ideal for displaying HTML markup, styled text content, or complete web pages. After that, you need to handle the Social button you're calling and the data submitted if any...
Responding To WKWebView Events With WKNavigationDelegate
A WKWebView web view has two main delegate protocols and properties:
navigationDelegate of type WKNavigationDelegate, which responds to
navigation events
uiDelegate of type WKUIDelegate, which responds to user
interaction events
Of these two delegate protocols, the WKNavigationDelegate is probably used most frequently. So, let’s hook into some page navigation events! We’ll do so with these delegate functions:
webView(_:didStartProvisionalNavigation:)
webView(_:didCommit:)
webView(_:didFinish:)
webView(_:didFail:withError:)
webView(_:didFailProvisionalNavigation:withError:)
First, let’s adopt the protocol and set the webView delegate. Here’s how:
Add the WKNavigationDelegate protocol to your view controller’s class declaration, like: class WebViewController: UIViewController, WKNavigationDelegate
Set the navigationDelegate property of webView to self, before loading the web request, like: webView?.navigationDelegate = self
Next, implement the five delegate functions described earlier. Set their function bodies to print(#function), so we can see the order in which the functions are called.
Like this:
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
{
print(#function)
}
Related
so I can't seem to figure out a way to perform some tasks before loading a url in ios webview.
Like in android we can use shouldOverrideUrlLoading.
#Override
public boolean shouldOverrideUrlLoading(final WebView view, String url) {
///sometask
}
but I can't find a function that does something like this in ios.
Say a user clicked on a href tag inside the webview that takes it to different page, how do I know what link that tag takes the user to? before changing the page.
Basically I want to check what url the webpage is about to load and perform extra steps according to that url.
You can use WKNavigationDelegate
set navigationDelegate in viewDidLoad
self.webView?.navigationDelegate = self
Observe URL in below navigationDelegate Method.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
DispatchQueue.main.async {
if let urlString = navigationAction.request.url?.absoluteString{
print(urlString)
}
}
decisionHandler(.allow)
}
I am using WKWebView for my WebViewController in my app and I spot one problem with one URL
"http://www.viator.com/tours/San-Francisco/San-Francisco-Vista-Grande-Helicopter-Tour/d651-3538VISTAGRANDE?eap=brand-subbrand-75523&aid=vba75523en" there is no navigation through the web site when I tap some other event page nothing happens. Does anyone have any ideas about how to deal with that?
If you're talking about links opening in a new window, indeed, they don't create a new navigation action. But you can still intercept them, and load the request manually.
If your webview does not have a custom uiDelegate already, assign it to your view controller or something else, and then do something like this:
extension SomeViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
// Intercept target=_blank links
guard
navigationAction.targetFrame == nil,
let url = navigationAction.request.url else {
return nil
}
let request = URLRequest(url: url)
webView.load(request)
return nil
}
}
I'm using WKWebview for my Swift app. For some reason, WKWebview navigation response delegate method isn't getting called when the user clicks the done button in a WKWebView. When I try the same action on the web, it redirects to the correct url.
So far I have tried clearing WKWebview cache before configuring WKWebView in viewDidLoad or if I get a memory warning. Also, ensured my info.plist allows arbitrary loads and NSExceptionAllowsInsecureHTTPLoads for testing purposes. Despite trying these things to debug, the navigation response delegate method still didn't get called.
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: #escaping (WKNavigationResponsePolicy) -> Void) {
if let webviewUrl = webView.url {
let urlString = webviewUrl.absoluteString
if urlString.contains("\(myUrlComponents)") {
self.navigationController?.popViewController(animated: true)
decisionHandler(.cancel)
return
}
}
decisionHandler(.allow)
}
I want to be able to detect a specific WKWebview url when the navigation response method gets called and go back to the previous screen.
I think you'll find that it will be called if you use the delegate function that looks identical to the one you're using except that the "decisionHandler" is a function taking WKNavigationActionPolicy as its argument.
I can't find solution for this. I hope You'll help me.
I want buttons with hyperlinks to open websites in webview on second screen. Hyperlink opens in safari and I want it to open on second screen in webview.
Thank you
You can use SFSafariViewController to open link in your application, here is the code for that
First you need to import SafariServices
import SafariServices
then on the button action, you can open SFSafariViewController
For swift 3.0
let svc = SFSafariViewController(url: URL(string:"http://stackoverflow.com")!)
self.present(svc, animated: true, completion: nil)
Swift 4.1 and Swift 5. If there are some links inside the app then it will open in safari, So to opens the links within same webview implement following navigationDelegate fo WKWebView.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == WKNavigationType.linkActivated {
webView.load(navigationAction.request)
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
In my view controller, I have a WKWebView and I use a UITapGestureRecognizer to detect taps on the webview in order to show/hide the navigation and status bars. I also use the taps+javascript to detect when special parts of the web content are tapped.
WKWebView uses long-presses to allow the user to select text.
Super-long-presses work great. The web content is selected by WKWebView as expected and life is good.
My problem is when the user applies "shorter"-long-presses, because the UITapGestureRecognizer recognizes them as taps. WKWebView selects the text, so it seems like the user pressed long enough, but upon release the UITapGestureRecognizer fires the designated action and my code to show/hide the navigation bar kicks in.
What I want is to only show/hide the navigation bar when the user applies a very short tap. If they touch long enough for WKWebView to select text, I want to let WKWebView handle it.
I was hoping to filter taps by touch duration, but I haven't been able to find a way to determine this information.
Am I missing something? Can I achieve this with a UITapGestureRecognizer or do I need a different approach?
I'm targetting iOS 8 & 9.
If you have access to the gesture recognizer used by the WKWebView that selects the text, then you can setup your short tap recognizer to require that WKWebView recognizer to fail, using requireGestureRecognizerToFail:.
If you don't have access to the gesture recognizer used by the WKWebView, then you can take this hackier approach:
Create a UILongPressGestureRecognizer. This long press recognizer doesn't do anything on its own, but it's needed by step 2.
In your short tap recognizer, use requireGestureRecognizerToFail:, specifying the UILongPressGestureRecognizer from step 1.
Note, this second approach only has a shot of working if WKWebView is using a UILongPressGestureRecognizer under the hood.
For WKWebView the most simple solution will be just to use method from WKNavigationDelegate protocol and inside of it decide whether to handle that url or not.
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url, url.scheme?.lowercased() == Constants.mailToScheme {
UIApplication.shared.open(url, options: [:])
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
If #melany code does't work properly then make following changes ...
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: ((WKNavigationActionPolicy) -> Void)) {
switch navigationAction.navigationType {
case .linkActivated:
UIApplication.shared.openURL(navigationAction.request.url!)
decisionHandler(.cancel)
return
default:
break
}
decisionHandler(.allow)
}