我在 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...
}
}
}
}
我走在正确的道路上还是应该以不同的方式处理这个问题?
我不相信你走在正确的道路上。
命中测试和
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
}
}
}
如果您有更复杂的要求,请提供更多信息。否则我希望这能让你走上正轨。