iOS UIPanGestureRecognizer:调整灵敏度?

sh3*_*211 5 ios uipangesturerecognizer swift

我的问题:有没有办法调整 UIPanGestureRecognizer 的“灵敏度”,使其“更快”打开,即在移动较少数量的“像素”之后?

我有一个带有 UIImageView 的简单应用程序,以及与之相关的捏合和平移手势识别器,以便用户可以手动放大和绘制图像。工作正常。

但是,我注意到库存 UIPanGestureRecognizer 不会返回 UIGestureRecognizerState.Changed 的​​值,直到用户的手势移动大约 10 个像素。

示例:这是一个屏幕截图,显示了我尝试画得越来越短的几条线,并且有一个明显的有限长度,低于该长度就不会绘制任何线,因为平移手势识别器永远不会改变状态。

IllustrationOfProgressivelyShorterLines.png

...即,在黄线的右侧,我仍在尝试绘制,并且我的触摸被识别为 TouchMoved 事件,但 UIPanGestureRecognizer 没有触发自己的“Moved”事件,因此没有绘制任何内容。

(注/说明:该图像占据了我的 iPad 的整个屏幕,因此即使在识别器没有发生状态变化的情况下,我的手指也会物理移动超过一英寸。只是我们“放大”了根据捏合手势识别器生成的转换,因此图像的几个“像素”占据了屏幕的很大一部分。)

这不是我想要的。关于如何修复它有什么想法吗?

如果我对 UIPanGestureRecognizer 进行子类化或类似的东西,也许我可以得到 UIPanGestureRecognizer 的一些“内部”参数?我想我会尝试以某种方式对识别器进行子类化,例如......

class BetterPanGestureRecognizer: UIPanGestureRecognizer {

    var initialTouchLocation: CGPoint!

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        initialTouchLocation = touches.first!.locationInView(view)
        print("pan: touch begin detected")
        print(self.state.hashValue)  // this lets me check the state
    }


    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        print("pan: touch move detected")
        print(self.state.hashValue)  // this remains at the "began" value until you get beyond about 10 pixels
        let some_criterion =  (touches.first!.isEqual(something) && event.isEqual(somethingElse))
        if (some_criterion) {
            self.state = UIGestureRecognizerState.Changed
       }
    }

}
Run Code Online (Sandbox Code Playgroud)

...但我不确定如何使用 some_criterion 等。
有什么建议吗?

其他可行的替代方案,但我不想这样做:

  1. 可以简单地将 UIPanGestureRecognizer 连接到某个父级非缩放视图,然后使用仿射变换等将平移触摸的点重新映射到图像的相应部分。那么我为什么不这样做呢?因为代码的编写使得许多其他对象挂在图像视图上,并且它们都获得相同的手势识别器,并且......一切都很好,而无需我跟踪任何东西(例如仿射变换),而问题只是如果你真的放大了,就会出现。
  2. 我可以放弃 UIPanGestureRecognizer,并有效地使用 TouchBegan 和 TouchMoved 编写自己的内容(这就是我正在做的事情),但是我喜欢 UIPanGestureRecognizer 与捏事件的区别,以一种我没有的方式担心自己编码。
  3. 我可以指定一些用户不能超出的最大缩放比例。这无法实现我想要的,即我想要允许精细细节级别的操作。

谢谢。

sh3*_*211 3

[如果值得的话,会选择你的答案而不是我的答案(即以下),所以我还不会“接受”这个答案。]

知道了。该解决方案的基本思想是在触摸移动时更改状态,但使用关于同步手势识别器的委托方法,以免“锁定”任何捏合(或旋转)手势。这将允许根据您的需要进行单指和/或多指平移,而不会出现“冲突”。

这就是我的代码:

class BetterPanGestureRecognizer: UIPanGestureRecognizer, UIGestureRecognizerDelegate {

    var initialTouchLocation: CGPoint!

    override init(target: AnyObject?, action: Selector) {
        super.init(target: target, action: action)
        self.delegate = self
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        initialTouchLocation = touches.first!.locationInView(view)
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        if UIGestureRecognizerState.Possible == self.state {
           self.state = UIGestureRecognizerState.Changed
        }
    }

    func gestureRecognizer(_: UIGestureRecognizer,
        shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
            if !(shouldRecognizeSimultaneouslyWithGestureRecognizer is UIPanGestureRecognizer) {
                return true
            } else {
                return false
            }
    }

}
Run Code Online (Sandbox Code Playgroud)

通常将“shouldRecognizeSimultaneouslyWithGestureRecognizer”委托设置为 true始终是许多人可能想要的。如果另一个识别器是另一个 Pan,我会让委托返回 false,只是因为我注意到如果没有这种逻辑(即,无论怎样让委托返回 true),它就会“传递”Pan 手势到底层视图,并且我不想那样。无论如何,你可能只是想让它返回 true。干杯。