26

Does there exist something like a onLinkClickListener in the WKWebView class? I tried googling it but found nothing, I also found some unanswered questions on stackoverflow of simillar type.

The reason I need a linkClickListener is that, when I click on a link and the page did not load yet, it does not load the website. I also could create a fancy loading screen, when the page is loading with the listener.

Shamas S
  • 7,507
  • 10
  • 46
  • 58
Samuel Kodytek
  • 1,004
  • 2
  • 11
  • 23
  • Have you looked at the documentation for WKNavigationDelegate? From your question it seems you are not so much concerned about detecting the click (onClick in Javascript parlance) but seeing what is happening with the subsequent page load. WKNavigationDelegate's methods allow you to track what is going on here, respond to authentication challenges etc.If this is what you need let me know and I'll post an answer. – Marcus Sep 16 '17 at 12:56
  • @Sparky I need the clickListener so I could move to front a fancy little loading view and then when the page loads, hide it, that would solve this problem and make the app nicer I think. – Samuel Kodytek Sep 16 '17 at 12:58
  • 1
    I see what you mean and I think WKNavigation delegate could do it for you. When you initiate the new page load, present your progress indicator or whatever you want to show, then use the delegate callbacks to show progress of the load (if it's a big page) and then confirm that the page has successfully loaded. – Marcus Sep 16 '17 at 13:02
  • @SamuelKodytek Did you handled onClick listener in webview in Any way? Please help. – Shangari C Nov 03 '22 at 14:34

2 Answers2

61

You can do it like this

add WKNavigationDelegate to your class

class ViewController: UIViewController, WKNavigationDelegate

set a navigation delegate

yourWKWebview.navigationDelegate = self

after that you will be able to use decidePolicyFor navigationAction function

 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if navigationAction.navigationType == WKNavigationType.linkActivated {
            print("link")

            decisionHandler(WKNavigationActionPolicy.cancel)
            return
        }
        print("no link")
        decisionHandler(WKNavigationActionPolicy.allow)
 }
Vitaly Migunov
  • 4,297
  • 2
  • 19
  • 23
2

Here is the solution you were looking for

Original answer from Bala: https://stackoverflow.com/a/44408807/8661382

Create WkNavigationDelegate to your class:

class ViewController: UIViewController, WKNavigationDelegate {
    }

Override the method loadView and add an observer like this:

override func loadView() {
        webView = WKWebView()
        webView.navigationDelegate = self
        webView.addObserver(self, forKeyPath: "URL", options: [.new, .old], context: nil)
        view = webView
    }

In viewDidLoad add an url to your webView.:

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.setNavigationBarHidden(false, animated: true)
    
    let url = URL(string: "https://www.hackingwithswift.com")!
    webView.load(URLRequest(url: url))
    webView.allowsBackForwardNavigationGestures = true
    }

Finally, most importantly override observerValue method like this:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, 
    change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let newValue = change?[.newKey] as? Int, let oldValue = change? 
    [.oldKey] as? Int, newValue != oldValue {
        //Value Changed
        print(change?[.newKey] as Any)
    }else{
        //Value not Changed
        print(change?[.oldKey] as Any)
    }
    }

This will print the link you click on webView before loading the link.