UIView和UITableView中的UITapGestureRecognizer冲突问题

25

我有一个UIView,其中添加了一个UITapGestureRecognizer。在该视图内,我还有一个子视图,基本上是一种UITableView。问题是,为什么UITableView不能识别行上的轻拍,而总是转到轻拍手势识别器的处理程序。为什么会这样,我该如何解决?如果将轻拍次数设置为2,则可以正常工作。有什么解决办法吗?基本上它不调用didSelectRowAtIndexPath

2个回答

54

将您的识别器 (recognizer) 的 cancelsTouchesInView 设置为 NO。否则,它将"消耗"该触摸事件并不会将其传递给表视图。这就是为什么选择事件从未发生的原因。


4
将该值设置为“NO”会指示识别器将所有触摸传递给底层视图,即使它已经识别了序列。 - Sergey Kalinichenko
1
示例代码 'longPressGestureRecognizer.cancelsTouchesInView = NO;'(感谢dasblinkenlight) - tmr
@dasblinkenlight 对我仍然没有用,我无法在我的表视图单元格上执行触摸事件,我无法选择表视图单元格中的项目,我已经使用了func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)但是项目没有被选中。 - Samarth Kejriwal

27
如果您希望 同时 让您的 UITableView 和您的 UITapGestureRecognizer 都能接收到触摸事件,那么是的,cancelsTouchesInView = NO 将起作用。如果您想让点击手势识别器不接收专门用于表视图的触摸事件,则略微有些复杂,但非常可行。
基本上,在创建手势识别器时,将其委托设置为 self。然后实现 gestureRecognizer:shouldReceiveTouch: 委托方法即可。一个基本的实现可能如下所示。
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    UITableView *tableView = self.tableView;
    CGPoint touchPoint = [touch locationInView:tableView];
    return ![tableView hitTest:touchPoint withEvent:nil];
}

本质上,这种方法(如实现的那样)会询问tableView是否该触摸位置在tableView的管辖范围内,如果是,则会阻止手势识别器接收该触摸...从而允许tableView接收该触摸。


1
我们能不能通过将第3行和第4行改为以下内容来简化这个过程呢:CGRect frame = self.tableView.frame; return !CGRectContainsPoint(frame, location); - Aufwind
@Aufwind 感谢你指出我过于复杂的计算代码。我可能在回答时匆忙了一些。CGRectContainsPoint() 绝对是处理这个计算的更好方式,比我最初选择的方法要好得多。不过,我已经编辑了我的答案,使用了 hitTest:withEvent: 方法。这是我首选的方法,原因有几个。其中之一是处理不规则形状的视图。如果一个视图呈现为不规则形状(例如只在圆形区域内响应触摸),手动计算就无法正确处理这种情况。再次感谢你的指正。 - NJones
1
这是正确的答案。应该被选择。 - Borzh
如果我的视图不知道其子视图中是否有表视图怎么办? - iosdude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接