如何捕获最初在UIPanGestureRecognizer中点击的点?

tod*_*412 23 iphone objective-c pan uigesturerecognizer ios

我有一个应用程序,让用户跟踪屏幕上的行.我是通过在UIPanGestureRecognizer中记录点来实现的:

-(void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
    CGPoint pixelPos = [recognizer locationInView:rootViewController.glView];
    NSLog(@"recorded point %f,%f",pixelPos.x,pixelPos.y);
}
Run Code Online (Sandbox Code Playgroud)

这很好.但是,我对用户在开始平移之前点击的第一点非常感兴趣.但上面的代码只给出了手势被识别为平底锅的点数(相对于水龙头).

从文档中可以看出,可能没有简单的方法来确定UIPanGestureRecognizer API中最初挖掘的位置.虽然在UIPanGestureRecognizer.h中,我发现了这个声明:

CGPoint _firstScreenLocation;
Run Code Online (Sandbox Code Playgroud)

......似乎是私人的,所以没有运气.我正在考虑完全离开UIGestureRecognizer系统只是为了捕获那个初始点,然后在我知道用户确实已经开始UIPanGesture之后再回头看它.我想我会问这里,然后走这条路.

小智 24

迟到了,但我注意到上面没有任何内容实际上回答了这个问题,实际上有一种方法可以做到这一点.您必须继承UIPanGestureRecognizer的子类并包括:

#import <UIKit/UIGestureRecognizerSubclass.h>
Run Code Online (Sandbox Code Playgroud)

在您编写类的Objective-C文件中或在Swift桥接头中.这将允许您覆盖touchesBegan:withEvent方法,如下所示:

class SomeCoolPanGestureRecognizer: UIPanGestureRecognizer {
    private var initialTouchLocation: CGPoint!

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

然后您的属性initialTouchLocation将包含您寻找的信息.当然在我的例子中,我假设触摸集中的第一次触摸是感兴趣的,如果你有一个1的maximumNumberOfTouches,这是有道理的.你可能想要使用更复杂的方法来寻找感兴趣的触摸.

  • 在Swift中,您可以将以下行添加到子类文件中,而不是使用桥接头:import UIKit.UIGestureRecognizerSubclass (4认同)
  • 这应该是选定的答案. (2认同)

Dee*_*olu 20

translationInView:除非您在两者之间重置,否则您应该可以使用它来计算起始位置.获取翻译和触摸的当前位置,并使用它来找到触摸的起点.


Bre*_*ust 9

@John Lawrence说得对.

针对Swift 3进行了更新:

import UIKit.UIGestureRecognizerSubclass

class PanRecognizerWithInitialTouch : UIPanGestureRecognizer {
  var initialTouchLocation: CGPoint!

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
    super.touchesBegan(touches, with: event)
    initialTouchLocation = touches.first!.location(in: view)
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意initialTouchLocation,如果要从子类实例(处理程序)访问实例变量,则实例变量不能是私有的.

现在在处理程序中,

  func handlePan (_ sender: PanRecognizerWithInitialTouch) {
    let pos = sender.location(in: view)

    switch (sender.state) {
    case UIGestureRecognizerState.began:
      print("Pan Start at \(sender.initialTouchLocation)")

    case UIGestureRecognizerState.changed:
      print("    Move to \(pos)")
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用以下方法:

CGPoint point    = [gesture locationInView:self.view];
Run Code Online (Sandbox Code Playgroud)

  • 这提供了平移手势的当前位置,而不是初始点。 (5认同)