WKWebview 允许 BackForwardNavigationGestures 和 UINavigationController InteractivePopGestureRecognizer 均启用

问题描述 投票:0回答:4

嵌入导航控制器中的我的视图控制器包含一个 WKWebview,我想在其上启用以下逻辑:

如果 web 视图中存在后退项,则做出左屏幕边缘手势应该返回 web 视图中的一页(当 allowedBackForwardNavigationGestures 设置为 yes 时,web 视图的正常行为)。当没有任何后退项时,它应该在导航控制器(interactivePopGestureRecognizer)中弹出一页。我启用了两者,并得到随机结果,有时我返回网络视图中的一页,有时我返回导航堆栈中的主页。我尝试了以下逻辑:

-(void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {

  if (webView.backForwardList.backItem) {
    MYappDelegate.mainNavigationController.interactivePopGestureRecognizer.enabled = NO;
    self.webView.allowsBackForwardNavigationGestures = YES;
  } else {
    MYappDelegate.mainNavigationController.interactivePopGestureRecognizer.enabled = YES;
    self.webView.allowsBackForwardNavigationGestures = NO;
  }
}

但是当我滑动时它崩溃了,并且收到“WKCompositingView 无法识别的选择器发送到实例。”

有什么想法我哪里出错了吗?我猜想哪个手势优先存在冲突,但我不知道在哪里添加这个逻辑,所以 webview 和包含其视图控制器的导航控制器都能和平相处。

ios uinavigationcontroller wkwebview
4个回答
3
投票
_webView.allowsBackForwardNavigationGestures = YES;

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    self.navigationController.interactivePopGestureRecognizer.enabled = _webView.canGoBack ? NO : YES;
}

1
投票

我也有同样的问题。请尝试以下方法:

首先,向WebView添加自定义手势:

    let swipe = UISwipeGestureRecognizer(target: self, action: #selector(goBack))
    swipe.direction = UISwipeGestureRecognizerDirection.right
    swipe.delegate = self.navigationController
    webView.addGestureRecognizer(swipe)

然后,添加一个UIGestureDelegate方法来同时处理手势,

extension UINavigationController: UIGestureRecognizerDelegate{
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return gestureRecognizer is UIScreenEdgePanGestureRecognizer
}

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

}

但它有一个小缺陷,滑动效果与原生不同,滑动时无需触摸即可显示新的 viewController。


1
投票

也许你可以使用 canGoback 的观察者,比如

RACObserve(self.wk_webView, canGoBack)

如果该值为 true,则执行

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

0
投票
import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, UIGestureRecognizerDelegate {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView = WKWebView(frame: self.view.bounds)
        webView.navigationDelegate = self
        // Step1: enable webview right-swipe to return the previous URL
        webView.allowsBackForwardNavigationGestures = true
        self.view.addSubview(webView)
        
        if let url = URL(string: "https://example.com") {
            let request = URLRequest(url: url)
            webView.load(request)
        }
        
        // Step2: control whether right-swipe to popViewController in gestureRecognizerShouldBegin function
        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    }

    // Step3: if webView cannot go back, enable interactivePopGestureRecognizer(right-swipe to popViewController)
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return !(webView.canGoBack)
    }

    // Step4: when webView finish load, determine whether the interaction gesture of navigationController is enabled
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = !webView.canGoBack
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.