使用 hittest 和 UIGestureRecognizer 来确定使用哪个视图

问题描述 投票:0回答:1

我在 MapView 上方有一个 UIImageView。 屏幕上的所有操作都应该转到touchesBegan,除了捏合,捏合应该放大和缩小下面的地图。

我认为实现这一点的方法是在命中测试中,因为这似乎是我可以返回 UIImageView 或 MapView 的唯一地方。然而,我无法检查命中测试中使用了哪个 UIGestureRecognizer,因此我无法确定应返回哪个视图。

class ViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate, UIGestureRecognizerDelegate {
    @IBOutlet weak var myMapView: GMSMapView!
    myMapView.delegate = self

    @objc func handlePinch(_ sender: UIPinchGestureRecognizer? = nil) {
        //Do something
    }

   lazy var canvasView: CanvasView = {
        var overlayView = CanvasView(frame: CGRect(x:0, y: 0, width: self.myMapView.frame.width, height: self.myMapView.frame.height))
        overlayView.isUserInteractionEnabled = true
        overlayView.delegate = self

        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch))
        pinchGesture.delegate = self
        overlayView.addGestureRecognizer(pinchGesture)

        return overlayView
    }()

    class CanvasView: UIImageView {
        var lastPoint = CGPoint.zero
        
        override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            var view = super.hitTest(point, with: event)

            //if pinch is detected return view else return nil
        }

        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            if let touch = touches.first {
                //Do something...
            }
        }
    }
}    

我走在正确的道路上还是应该以不同的方式处理这个问题?

ios swift uigesturerecognizer hittest
1个回答
0
投票

我不相信你走在正确的道路上。

命中测试和

touchesBegan
(以及其他)应该位于手势识别器下方,并且应该在任何手势识别器之前调用。这意味着您需要始终返回
overlayView
中的
CanvasView
(
hitTest
)。如果您不这样做:

  • 如果尚未检测到手势识别器,则永远不会检测到
  • 如果检测到手势识别器,它将停止响应

您没有给我们太多信息,但从我读到的内容来看,我认为您实际上只是想跟踪识别器何时进行,并在这种情况下以不同的方式处理事件:

private var isPinchingInProgress: Bool = false {
    didSet {
        canvasView.isPinchingInProgress = isPinchingInProgress
    }
}

@objc func handlePinch(_ sender: UIPinchGestureRecognizer? = nil) {
    guard let sender else { return }
    switch sender.state {
    case .began:
        isPinchingInProgress = true
    case .changed:
        // Do your stuff here most likely
        break
    case .ended, .cancelled:
        isPinchingInProgress = false
    case .possible, .failed:
        // ¯\_(ツ)_/¯
        break
    @unknown default:
        fatalError()
    }
}

class CanvasView: UIImageView {
    
    var isPinchingInProgress: Bool = false
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        var view = super.hitTest(point, with: event)
        if isPinchingInProgress {
            // Ignore?
        } else {
            // Do stuff here
        }
    }
}

如果您有更复杂的要求,请提供更多信息。否则我希望这能让你走上正轨。

© www.soinside.com 2019 - 2024. All rights reserved.