5

I am using a WKWebView and I allowed back and forward navigation gestures :

myWkWebView.allowsBackForwardNavigationGestures = true

Now, the user has two ways to go back : either by pushing a button or by swiping left. The behaviors would be different, so I am wondering how I can know when a user has just swiped left / right so I can handle this.

I looked into WKNavigationDelegate reference ( https://developer.apple.com/library/ios/documentation/WebKit/Reference/WKNavigationDelegate_Ref/ ) but I couldn't find anything useful.

Any idea ?

EDIT

I forgot to say that I also tried to add swipe gesture recognizers, this way :

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(MyVC.respondToSwipeLeftOrRight(_:)))
    swipeRight.direction = UISwipeGestureRecognizerDirection.Right
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(MyVC.respondToSwipeLeftOrRight(_:)))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
    self.view.addGestureRecognizer(swipeRight)
    self.view.addGestureRecognizer(swipeLeft)
    myWkWebView.scrollView.panGestureRecognizer.requireGestureRecognizerToFail(swipeRight)
    myWkWebView.scrollView.panGestureRecognizer.requireGestureRecognizerToFail(swipeLeft)

But they are not triggered everytime I swipe left or right.

Randy
  • 4,335
  • 3
  • 30
  • 64

3 Answers3

3
private var currentBackForwardItem: WKBackForwardListItem?
private func handleBackForwardWebView(navigationAction: WKNavigationAction) {
    if navigationAction.navigationType == .BackForward {
        let isBack = webView.backForwardList.backList
            .filter { $0 == currentBackForwardItem }
            .count == 0

        if isBack {

        } else {

        }
    }

    currentBackForwardItem = webView.backForwardList.currentItem
}

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
    handleBackForwardWebView(navigationAction)
    decisionHandler(.Allow)
}
binhapp
  • 409
  • 5
  • 10
  • Please note, that in a SinglePageApplication with a Framework like angular, there is only a route change and the WKWebView only fires its functions when a full page load happens. https://stackoverflow.com/questions/47829963/how-can-i-detect-when-url-of-amp-page-changed-with-wkwebview Which means you will not get a method call here if you navigate in an angular or ionic application. – Stefan Rein May 22 '19 at 11:49
0

You should be able to do this with your gesture recognizers, but you need to implement shouldRecognizeSimultaneouslyWithGestureRecognizer method from UIGestureRecognizerDelegate if you want to handle several gesture recognizers on single view:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}
Vladimir K
  • 1,382
  • 1
  • 12
  • 27
  • Hi Vladimir, thanks for your answer, I have already implemented this method, the gesture recognizers are just "less sensitive" than the ones implemented internally within the `WKWebView` – Randy May 16 '16 at 11:07
  • I can assume that requireGestureRecognizerToFail methods causing problems with sensitivity. You can try to remove them, since shouldRecognizeSimultaneouslyWithGestureRecognizer method should support all gestures. – Vladimir K May 16 '16 at 11:25
  • Where does this go? In the ViewController? – applecrusher Dec 10 '16 at 23:43
0

Seeing that a SinglePageApplication wont work as Stefan Rein says we could incorporate the linked solution by checking the web view's gesture recognizers.

[self.webView addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil];
//....
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)context {
  if ([keyPath isEqualToString:@"URL"]) {    
    for (UIGestureRecognizer *recognizer in self.webView.gestureRecognizers) {
      if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        if (((UIPanGestureRecognizer*)recognizer).state == UIGestureRecognizerStateEnded) {
          NSLog(@"Swiped!");
        }
      }
    }
  }
}

Of course if you have other gestures other than the two for forward and back then you might need to do more checks.

richy
  • 2,716
  • 1
  • 33
  • 42