为什么我的 UITapGestureRecognizer 在我将它附加到 UITableViewCell 中的元素时不起作用?

Why does my UITapGestureRecognizer doesn't work when I attach it to the element in my UITableViewCell?

我想覆盖双击 mapView 的默认行为。

在我的 swift 应用程序中,我在静态单元格中有一个 mapView,因此在方法 cellForRowAt 中我决定添加一个 UITapGestureRecognizer。我是这样做的:

func tableView(_ myTable: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if (indexPath as NSIndexPath).row == 0 {
        let cell = myTable.dequeueReusableCell(withIdentifier: "cellStatic") as! MyTableDetailsCell

        cell.mapView.isScrollEnabled = false //this works

        //this does not:
        let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
        tap.numberOfTapsRequired = 2
        cell.mapView.addGestureRecognizer(tap)
        ...

然后我有一个简单的函数:

func doubleTapped() {
    print("map tapped twice")
}

但是当我点击两次地图时 - 它放大并且控制台日志中没有打印 - 所以我的代码不起作用。我错过了什么?

尝试使用 touchesBegan 来识别触摸事件,您可以在事件触发时调用您的自定义处理程序

您必须强制您自己的双击手势识别器禁用 mapView 的标准双击手势识别器。
这可以使用委托方法完成:

使用 UIGestureRecognizerDelegate

将您的视图控制器声明为手势识别器的委托

为您自己的双击手势识别器定义 属性:

var myDoubleTapGestureRecognizer: UITapGestureRecognizer?  

设置双击手势识别器,例如在 viewDidLoad 中:

myDoubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
myDoubleTapGestureRecognizer!.numberOfTapsRequired = 2
myDoubleTapGestureRecognizer!.delegate = self
mapView.addGestureRecognizer(myDoubleTapGestureRecognizer!)

注意,这里设置的是delegate。

实现以下委托方法:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
                       shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    if ((gestureRecognizer == myDoubleTapGestureRecognizer) && (otherGestureRecognizer is UITapGestureRecognizer)) {
        let otherTapGestureRecognizer = otherGestureRecognizer as! UITapGestureRecognizer
        return otherTapGestureRecognizer.numberOfTapsRequired == 2
    }
    return true
}  

因此,当您双击 mapView 时,此委托方法 returns true 如果另一个手势识别器是 [=13= 的内置双击识别器].这意味着内置的双击识别器只能在您自己的双击识别器无法识别双击时触发,而它不会。
我测试了一下:地图不再缩放,调用方法doubleTapped.

将地图视图添加为tableViewCell 中容器视图的子视图。设置约束,使地图视图填充整个容器视图。禁用地图视图的用户交互并将双击手势添加到容器视图。此代码会有所帮助。

    let cell = myTable.dequeueReusableCell(withIdentifier: "cellStatic") as! MyTableDetailsCell
    let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
    cell.mapView.isUserInteractionEnabled = false
    cell.containerView.addGestureRecognizer(tap)
    tap.numberOfTapsRequired = 2

现在,当点击两次地图视图时,将调用 "doubleTapped" 选择器。禁用所有其他用户交互,包括地图视图的旋转手势。