11

I have a view that contains a WKWebView. My html content is generated by my app, so I know for sure it is never wider than the screen, so I'm using UIGestureRecognizers on its superview to react to left and right swipes. That works great.

I would also like to see any tap that is not on a link so I can decide what I might want to do with those. It appears that WKWebView sucks up all taps. I tried asking it for its array of gesture recognizers so that I could set up some cooperation with them, but I get nil no matter when I ask (i.e. after creating the WKWebView, after loading it with my HTML file, and when notified that it has finished loading). This makes sense if WKWebView isn't using the UIGestureRecognizer mechanism but instead is just watching for taps and not passing them along if it turns out it is not interested in them.

Any ideas for getting access to WKWebView's unwanted taps?

Craig
  • 3,253
  • 5
  • 29
  • 43

2 Answers2

11

Turns out the solution to this is to turn the problem inside out. I put a transparent UIView over the WKWebView and attached several UIGestureRecognizers to my transparent view. I use JavaScript calls to react to pan gestures. When a tap is recognized on my transparent view, I query the DOM to see if it is a link and if not, I can do whatever I want with it. Another benefit is that I get to handle long press, which is something I wanted to do instead of letting WKWebView do its baked-in, unchangeable behavior. This works really well.

Craig
  • 3,253
  • 5
  • 29
  • 43
  • Craig, how did you manage to have scrolling enabled inside with WKWebView after you put the transparent UIView on top? Appreciate if you can let know please as struggling with the same...! Thanks! – vikram17000 May 17 '16 at 21:40
  • I have a UIPanGestureRecognizer that looks at the velocity when the gesture ends. If it is > 100 or < -100, it calls javascript methods to start a kinetic scroll. I think I followed the basic pattern in this article: http://ariya.ofilabs.com/2013/11/javascript-kinetic-scrolling-part-2.html (for some reason I didn't comment on it in my source so I don't remember where it came from, but this article looks familiar). – Craig May 19 '16 at 18:00
  • This has been working really well for six months, by the way. I kind of forget that it's there. I am intercepting all touches to the WKWebView and routing them appropriate, including links, long presses, swipes, panes, taps, double-taps, etc. :-) – Craig May 19 '16 at 18:01
  • @Craig You have saved me SO much time! Thanks for that. It definitely works for my specific use case because I want to be able to drag around the WKWebView etc. – tech4242 Jul 21 '16 at 19:10
11

Swift 3.0 working solution, should work with Obj-C the same way (haven't tested)

...

let gesture = UITapGestureRecognizer(target: self, 
                                     action: #selector(gotTap(gesture:))
)
gesture.delegate = self
self.webView?.scrollView.addGestureRecognizer(gesture)

...

func gotTap(gesture:UITapGestureRecognizer) {
    print("gotTap")
//    self.webView?.scrollView.removeGestureRecognizer(gesture)
}

// MARK: UIGestureRecognizerDelegate method
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                       shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}
Deniss Fedotovs
  • 1,384
  • 12
  • 22