如何仅检测短敲击
How to detect only short taps
在我的视图控制器中,我有一个 WKWebView
并且我使用 UITapGestureRecognizer
来检测网络视图上的点击,以便 show/hide 导航栏和状态栏。我还使用 taps+javascript 来检测 Web 内容的特殊部分何时被点击。
WKWebView 使用长按允许用户 select 文本。
超级长按效果很好。网页内容select按预期由 WKWebView 编辑,生活很好。
我的问题是当用户应用 "shorter" 长按时,因为 UITapGestureRecognizer 将它们识别为点击。 WKWebView select 是文本,所以看起来用户按下的时间足够长,但在释放 UITapGestureRecognizer 时会触发指定的操作,并且我的代码 show/hide 导航栏会启动。
我想要的是仅 show/hide 用户轻按一下时的导航栏。如果他们触摸足够长的时间让 WKWebView 到 select 文本,我想让 WKWebView 处理它。
我希望通过触摸持续时间来过滤点击,但我一直无法找到确定此信息的方法。
我错过了什么吗?我可以使用 UITapGestureRecognizer 实现此目的还是需要其他方法?
我的目标是 iOS 8 和 9。
如果您有权访问选择文本的 WKWebView 使用的手势识别器,则可以使用 requireGestureRecognizerToFail:
.
设置短按识别器以要求 WKWebView 识别器失败
如果您无法访问 WKWebView 使用的手势识别器,那么您可以采用这种 hackier 方法:
- 创建一个
UILongPressGestureRecognizer
。这个长按识别器本身不会做任何事情,但是步骤 2 需要它。
- 在您的短按识别器中,使用
requireGestureRecognizerToFail:
,指定第 1 步中的 UILongPressGestureRecognizer
。
请注意,如果 WKWebView 在后台使用 UILongPressGestureRecognizer
,则第二种方法只能奏效。
对于 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)
}
}
如果@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)
}
在我的视图控制器中,我有一个 WKWebView
并且我使用 UITapGestureRecognizer
来检测网络视图上的点击,以便 show/hide 导航栏和状态栏。我还使用 taps+javascript 来检测 Web 内容的特殊部分何时被点击。
WKWebView 使用长按允许用户 select 文本。
超级长按效果很好。网页内容select按预期由 WKWebView 编辑,生活很好。
我的问题是当用户应用 "shorter" 长按时,因为 UITapGestureRecognizer 将它们识别为点击。 WKWebView select 是文本,所以看起来用户按下的时间足够长,但在释放 UITapGestureRecognizer 时会触发指定的操作,并且我的代码 show/hide 导航栏会启动。
我想要的是仅 show/hide 用户轻按一下时的导航栏。如果他们触摸足够长的时间让 WKWebView 到 select 文本,我想让 WKWebView 处理它。
我希望通过触摸持续时间来过滤点击,但我一直无法找到确定此信息的方法。
我错过了什么吗?我可以使用 UITapGestureRecognizer 实现此目的还是需要其他方法?
我的目标是 iOS 8 和 9。
如果您有权访问选择文本的 WKWebView 使用的手势识别器,则可以使用 requireGestureRecognizerToFail:
.
如果您无法访问 WKWebView 使用的手势识别器,那么您可以采用这种 hackier 方法:
- 创建一个
UILongPressGestureRecognizer
。这个长按识别器本身不会做任何事情,但是步骤 2 需要它。 - 在您的短按识别器中,使用
requireGestureRecognizerToFail:
,指定第 1 步中的UILongPressGestureRecognizer
。
请注意,如果 WKWebView 在后台使用 UILongPressGestureRecognizer
,则第二种方法只能奏效。
对于 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)
}
}
如果@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)
}