How do I capture the point initially tapped in a UIPanGestureRecognizer? How do I capture the point initially tapped in a UIPanGestureRecognizer? ios ios

How do I capture the point initially tapped in a UIPanGestureRecognizer?


Late to the party, but I notice that nothing above actually answers the question, and there is in fact a way to do this. You must subclass UIPanGestureRecognizer and include:

#import <UIKit/UIGestureRecognizerSubclass.h>

either in the Objective-C file in which you write the class or in your Swift bridging header. This will allow you to override the touchesBegan:withEvent method as follows:

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)    }}

Then your property initialTouchLocation will contain the information you seek. Of course in my example I make the assumption that the first touch in the set of touches is the one of interest, which makes sense if you have a maximumNumberOfTouches of 1. You may want to use more sophistication in finding the touch of interest.

Edit: Swift 5

import UIKit.UIGestureRecognizerSubclassclass InitialPanGestureRecognizer: UIPanGestureRecognizer {  private var initialTouchLocation: CGPoint!  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {    super.touchesBegan(touches, with: event)    initialTouchLocation = touches.first!.location(in: view)  }}


You should be able to use translationInView: to calculate the starting location unless you reset it in between. Get the translation and the current location of touch and use it to find the starting point of the touch.


@John Lawrence has it right.

Updated for Swift 3:

import UIKit.UIGestureRecognizerSubclassclass 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)  }}

Note that the instance variable initialTouchLocation cannot be private, if you want to access it from your subclass instance (handler).

Now in the handler,

  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)")