问题
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.
回答1:
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)
}
}
回答2:
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.
回答3:
@John Lawrence has it right.
Updated for 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)
}
}
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)")
回答4:
You could use this method:
CGPoint point = [gesture locationInView:self.view];
回答5:
in the same UIView put in this method.
//-----------------------------------------------------------------------
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint point = [[[event allTouches] anyObject] locationInView:self];
NSLog(@"point.x ,point.y : %f, %f",point.x ,point.y);
}
look for it in the UIGestureRecognizer Class Reference here: https://developer.apple.com/library/ios/documentation/uikit/reference/UIGestureRecognizer_Class/Reference/Reference.html
回答6:
You can use UIGestureRecognizerStateBegan method. Here is the link to Apple documentation on UIGestureRecognizer class.
http://developer.apple.com/library/ios/ipad/#documentation/uikit/reference/UIGestureRecognizer_Class/Reference/Reference.html%23//apple_ref/occ/cl/UIGestureRecognizer
回答7:
Wow, A couple years late.. I ran into this problem, but solved it with a static variable:
- (IBAction)handleGesture:(UIPanGestureRecognizer *)recog {
CGPoint loc = [recognizer locationInView:self.container];
static CGFloat origin = 0.0f;
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:
origin = loc.x;
break;
case UIGestureRecognizerStateChanged:
case UIGestureRecognizerStatePossible:
// origin is still set here to the original touch point!
break;
case UIGestureRecognizerStateEnded:
break;
case UIGestureRecognizerStateFailed:
case UIGestureRecognizerStateCancelled:
break;
}
}
The variable is only set when recognizer state is UIGestureRecognizerBegan. Since the variable is static, the value persists to later method calls.
For my case, I just needed the x coordinate, but you can change it to a CGPoint if you need.
来源:https://stackoverflow.com/questions/6950713/how-do-i-capture-the-point-initially-tapped-in-a-uipangesturerecognizer