UIGestureRecognizer.State 是 'possible' 而不是 'recognized' 每隔一次点击 MKMapView

UIGestureRecognizer.State is 'possible' and not 'recognized' every other click on an MKMapView

我正在尝试了解我的手势识别器的可重现错误。我在 MKMapView 上有 2 个识别器,一个 UITapGestureRecognizer 和一个 UILongPressGestureRecogniser。它们都是第一次按预期工作,但是,如果我使用长按(这会向地图添加注释),下一个点击手势将 return 处于 'possible' 状态但永远不会点击 'recognized'状态。

▿ Optional<Array<UIGestureRecognizer>>
  ▿ some : 2 elements
    - 0 : <UITapGestureRecognizer: 0x7fda7543ebc0; state = Possible; view = <MKMapView 0x7fda78026e00>>
    - 1 : <UILongPressGestureRecognizer: 0x7fda7543e8c0; state = Possible; view = <MKMapView 0x7fda78026e00>; numberOfTapsRequired = 0; minimumPressDuration = 0.2>

点击一次后没有任何反应,第二次点击会执行相关功能,即进入识别状态。

我拦截了 window 上的所有点击,每次点击肯定都会发生,但长按后的第一个点击似乎永远不会被接受。我在这里缺少什么吗?添加的手势如下:

let mapTap = UITapGestureRecognizer(target: self, action: #selector(mapTapped(_:)))
        mapView.addGestureRecognizer(mapTap)

let pressGesture = UILongPressGestureRecognizer(target: self, action: #selector(mapLongPress(_:)))
            pressGesture.minimumPressDuration = 0.2
            pressGesture.numberOfTouchesRequired = 1
            mapView.addGestureRecognizer(pressGesture)

这可能与 MKMapView 默认添加的其他手势有关吗?

在您的情况下,您希望点击识别器和长按识别器同时运行:当您点击视图时,两者都应该开始识别过程。当您在长按的最短点击时间之前结束点击时,应该触发点击手势,但当您稍后结束点击时,应该触发长按手势。
但是 Apple docs 说:

UIKit normally allows the recognition of only one gesture at a time on a single view. Recognizing only one gesture at a time is usually preferable because it prevents user input from triggering more than one action at a time. However, this default behavior can introduce unintended side effects. For example, in a view that contains both pan and swipe gesture recognizers, swipes are never recognized. Because the pan gesture recognizer is continuous, it always recognizes its gesture before the swipe gesture recognizer, which is discrete.

在您的情况下,长按手势识别器是连续的,而点按手势识别器是离散的,因此识别点按可能存在问题。

因此,我会尝试明确允许两个识别器同时识别他们的手势。 here.
给出了如何执行此操作的示例 一旦长按识别器触发,您可以取消点击识别器的识别操作。
希望这对您有所帮助!

我尝试使用您的代码并得到相同的结果。

我用一个棘手的方法解决了它。希望对你有所帮助

 mapTap = UITapGestureRecognizer(target: self, action: #selector(mapTapped(_:)))
 mapTap.delegate = self
 mapView.addGestureRecognizer(mapTap)
 
 pressGesture = UILongPressGestureRecognizer(target: self, action: 
                    #selector(mapLongPress(_:)))
                    pressGesture.minimumPressDuration = 0.2
                    pressGesture.numberOfTouchesRequired = 1
 mapView.addGestureRecognizer(pressGesture)

 @objc func mapTapped(_ gesture: UITapGestureRecognizer) {
    // your code
 }
 

 @objc func mapLongPress(_ gesture: UILongPressGestureRecognizer) {
    // your code
        
    if gesture.state == .began {
        mapTap.isEnabled = false
    } else if gesture.state == .cancelled || gesture.state == .ended {
        mapTap.isEnabled = true
    }
 }
   
 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
 }