I have an app that lets the user trace lines on the screen. I am doing so by recording the points within a UIPanGestureRecognizer:
-(void)handlePanFrom:(UIPanGestureRecognizer *)recognizer { CGPoint pixelPos = [recognizer locationInView:rootViewController.glView]; NSLog(@"recorded point %f,%f",pixelPos.x,pixelPos.y); }
That works fine. However, I'm very interested in the first point the user tapped before they began panning. But the code above only gives me the points that occurred after the gesture was recognized as a pan (vs. a tap.)
From the documentation, it appears there may be no easy way to determine the initially-tapped location within the UIPanGestureRecognizer API. Although within UIPanGestureRecognizer.h, I found this declaration:
CGPoint _firstScreenLocation;
...which appears to be private, so no luck. I'm considering going outside the UIGestureRecognizer system completely just to capture that initailly-tapped point, and later refer back to it once I know that the user has indeed begun a UIPanGesture. I Thought I would ask here, though, before going down that road.
A pinch gesture recognizer reports changes to the distance between two fingers touching the screen. Pinch gestures are continuous, so your action method is called each time the distance between the fingers changes. The distance between the fingers is reported as a scale factor.
UIGestureRecognizer tracks the touch behavior on-screen interpreted by the user such as tap, pinch, rotate, swipe, pan, and long press and acts on the recognition based on the action method written. With the introduction of UIGestureRecognizer, it definitely will save you more time from writing additional code.
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.UIGestureRecognizerSubclass class 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) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With