3

I have a WKWebView that I would like to handle touches but I just can't find the right method.

webView is created programmatically in viewDidLoad, and loads fine.

override func viewDidLoad() {
    super.viewDidLoad()
    let site = "http://google.com"
    let url = URL(string: site)
    let request = URLRequest(url: url!)
    webView = WKWebView(frame: self.view.frame)
    webView.navigationDelegate = self
    webView.uiDelegate = self // is this necessary for UITouch recognition?
    webView.load(request)
    self.view.addSubview(webView)
}

I've tried adding UITapGestureRecognizer in viewDidLoad... (per UIWebView and touch event)

override func viewDidLoad() {
    //...
    let taprecognizer = UITapGestureRecognizer(target: self, action: #selector(tapLocation))
    taprecognizer.numberOfTapsRequired = 1
    taprecognizer.delegate = self
    webView.addGestureRecognizer(taprecognizer)
}

func tapLocation(recognizer: UITapGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    print("tapped")
    return true
}

I've also tried getting touch from...

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("tapped")
}

My Debug View Hierarchy shows a bunch of WKCompositingViews which makes me think that these are using the touches before they can arrive to WKWebView or View. enter image description here

I've added UIViewController, UIWebViewDelegate, WKNavigationDelegate, WKUIDelegate, UIGestureRecognizerDelegate to class...but it just won't go through.

Chameleon
  • 1,608
  • 3
  • 21
  • 39
  • Were you able to fix this issue? – glo Jan 30 '18 at 09:00
  • You mean you want to handle touch in `WKWebView` or you want to handle links in WebView? – Jaydeep Vora Jan 30 '18 at 12:30
  • @Superman I was trying to handle touches occurring within the bounds of `WKWebview`. I believe I was doing so in order to use links, but I learned to use `evaluateJavaScript` instead so I still have found a solution to this issue. – Chameleon Jan 30 '18 at 13:03
  • How did you solve this with evaluateJavaScript? – Robert Veringa Sep 19 '18 at 10:10
  • @RobertVeringa i solved my goal. not this issue. – Chameleon Sep 24 '18 at 20:43
  • hi @Chameleon can i get the avplayer from debugging webview? see my question https://stackoverflow.com/questions/55377677/how-to-detect-avplayer-and-get-url-of-current-video-from-wkwebview/55443242?noredirect=1#comment97612916_55443242 – Virani Vivek Apr 02 '19 at 06:46

1 Answers1

1

Here is a sample working code in which i added WKWebView into main view and i am able to detect WKWebView touch event using UIGestureRecognizerDelegate

Swift4

    //
    //  WebViewVC.swift
    //
    //  Created by Test user on 01/02/18.
    //  Copyright © 2018 Test user. All rights reserved.
    //

    import UIKit
    import WebKit

    class WebViewVC: UIViewController,WKUIDelegate,UIGestureRecognizerDelegate {

        var webView : WKWebView!

        override func viewDidLoad() {
            super.viewDidLoad()
            let site = "http://google.com"
            let url = URL(string: site)
            let request = URLRequest(url: url!)
            webView = WKWebView(frame: self.view.frame)
            webView.uiDelegate = self // is this necessary for UITouch recognition?
            webView.load(request)
            self.view.addSubview(webView)

            let taprecognizer = UITapGestureRecognizer(target: self, action: #selector(tapLocation))
            taprecognizer.numberOfTapsRequired = 1
            taprecognizer.numberOfTouchesRequired = 1
            taprecognizer.delegate = self
            webView.addGestureRecognizer(taprecognizer)
        }

        @objc func tapLocation(recognizer: UITapGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            print("tapped")
            return true
        }

        func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            print("Tap event will detect here.")
            return true
        }

    }