快速手势识别器,仅跟踪连续手势中的首次触摸



我正在尝试使用手势识别器允许用户通过用一根手指拖动屏幕上的视图来调整视图的大小......因此,我想跟踪触摸的所有更改。我最初尝试为此使用PanGestureRecognizer,但是当用户用多个手指触摸视图时,我遇到了问题。我只想跟踪第一次触摸(即用户在手势过程中放在屏幕上的第一根手指),但我找不到一种方法来防止其他触摸干扰我跟踪第一次触摸的能力。我最初的解决方案是简单地设置

recognizer.maximumNumberOfTouches = 1

但是,这会导致在第二次触摸时取消整个手势(在这种情况下,我想继续跟踪第一次触摸)。但是,当然,不将此值设置为 1 会导致手势实际跟踪多个触摸。如何制作一个手势识别器,仅跟踪手势中第一个触摸的所有更改,并且不会因屏幕上的其他触摸而取消?

从您的评论和回答来看,听起来您使用平移手势识别器总是错误的,并且您在操作处理程序中做错了什么。平移手势识别器的正确操作处理程序永远不会将location(in:)用于任何操作。location(in:)给你一个所有触摸的质心,这正是你说你想要的——无论如何都没有必要咨询它。

  • 如果目标是拖动视图,请使用translation(in:)

  • 如果您的目标是跟踪特定触摸的实际位置,则可以使用location(ofTouch:in:)

  • 如果您发现正在传递触摸,并且不希望对其进行跟踪,请致电ignore(_:for:)

下面是一个 UIGestureRecognizer 子类,它将跟踪用户在手势开始时在屏幕上进行第一次触摸的所有更改,并将忽略所有其他手指而不取消手势。请注意,如果您使用的是手势识别器的函数/属性(例如location(in:)),您可能还必须覆盖这些函数/属性。

class FirstTouchGestureRecognizer: UIGestureRecognizer {
private var firstTouch: UITouch? = nil
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
if firstTouch == nil {
firstTouch = touches.first!
self.state = .began
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
if firstTouch != nil && touches.contains(firstTouch!) {
self.state = .changed
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
if firstTouch != nil && touches.contains(firstTouch!) {
firstTouch = nil
self.state = .ended
}
}
}