Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 421
todd412 Avatar asked Aug 05 '11 02:08

todd412


People also ask

How to use pinch gesture recognizer in swift?

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.

What is UIGestureRecognizer?

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.


1 Answers

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)   } } 
like image 67
John Lawrence Avatar answered Nov 05 '22 13:11

John Lawrence