【问题标题】:How to detect only short taps如何仅检测短敲击
【发布时间】:2015-11-18 22:33:07
【问题描述】:

在我的视图控制器中,我有一个WKWebView,我使用一个UITapGestureRecognizer 来检测 web 视图上的点击,以便显示/隐藏导航和状态栏。我还使用 taps+javascript 来检测网页内容的特殊部分何时被点击。

WKWebView 使用长按来允许用户选择文本。

超长按效果很好。网页内容按预期被WKWebView选中,生活不错。

我的问题是当用户应用“较短”的长按时,因为 UITapGestureRecognizer 将它们识别为点击。 WKWebView 选择文本,所以看起来用户按下了足够长的时间,但是在释放时,UITapGestureRecognizer 会触发指定的操作,并且我的代码来显示/隐藏导航栏。

我想要的是仅在用户应用非常短的点击时显示/隐藏导航栏。如果他们触摸足够长的时间让 WKWebView 选择文本,我想让 WKWebView 处理它。

我希望按触摸持续时间过滤点击,但我无法找到确定此信息的方法。

我错过了什么吗?我可以使用 UITapGestureRecognizer 实现这一点还是需要其他方法?

我的目标是 iOS 8 和 9。

【问题讨论】:

  • 也许您可以利用UITouch 属性timestamp。然后您可以检查- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event; 之间的时间差并采取相应措施。
  • 谢谢@BenJammin。我刚刚阅读了UIResponder 并将touchesBegan 和touchesEnded 添加到我的WKWebView 子类中。不幸的是,他们没有被召唤。我已经使用 NSLog 和断点来验证这一点。有什么想法吗?

标签: ios uikit uigesturerecognizer


【解决方案1】:

如果您有权访问选择文本的 WKWebView 使用的手势识别器,那么您可以使用 requireGestureRecognizerToFail: 设置您的短敲识别器以要求 WKWebView 识别器失败。

如果您无法访问 WKWebView 使用的手势识别器,那么您可以采用这种更骇人听闻的方法:

  1. 创建一个UILongPressGestureRecognizer。这个长按识别器本身不会做任何事情,但它是第 2 步所需要的。
  2. 在您的短按识别器中,使用requireGestureRecognizerToFail:,从步骤1 中指定UILongPressGestureRecognizer

注意,第二种方法只有在 WKWebView 在后台使用 UILongPressGestureRecognizer 时才有作用。

【讨论】:

  • 感谢道格的想法。我无法找到访问 WKWebView 识别器的方法。我停在一个带有断点的子类中。 WKWebView 上唯一的识别器是我添加的那个。我看了看它的scrollView,发现了3个UIScrollViewXYZGestureRecognizer。接下来,我实施了您的“hackier”方法,起初它似乎运行良好。我明天再测试一下,然后报告。
  • 谢谢,这对我帮助很大。我通过遍历 webView.scrollView.subviews 的手势识别器获得了我正在寻找的手势识别器:(虽然也有点 hacky)
【解决方案2】:

对于 WKWebView,最简单的解决方案就是使用 WKNavigationDelegate 协议中的方法,并在其中决定是否处理该 url。

public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
                      decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

    if let url = navigationAction.request.url, url.scheme?.lowercased() == Constants.mailToScheme {
      UIApplication.shared.open(url, options: [:])
      decisionHandler(.cancel)
    } else {
      decisionHandler(.allow)
    }
  }

【讨论】:

    【解决方案3】:

    如果@melany 代码无法正常工作,请进行以下更改...

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: ((WKNavigationActionPolicy) -> Void)) {
    
            switch navigationAction.navigationType {
            case .linkActivated:
                UIApplication.shared.openURL(navigationAction.request.url!)
                decisionHandler(.cancel)
                return
            default:
                break
            }
            decisionHandler(.allow)
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-17
      • 2015-07-27
      • 1970-01-01
      • 2022-07-13
      • 2014-07-01
      • 2011-08-16
      • 2021-11-08
      • 1970-01-01
      相关资源
      最近更新 更多