57

I want to get the UITouch location of my tap from UIGestureRecognizer, but I can not figure out how to from looking at both the documentation and other SO questions. Can one of you guide me?

- (void)handleTap:(UITapGestureRecognizer *)tapRecognizer
{
    CCLOG(@"Single tap");
    UITouch *locationOfTap = tapRecognizer; //This doesn't work

    CGPoint touchLocation = [_tileMap convertTouchToNodeSpace:locationOfTap];
    //convertTouchToNodeSpace requires UITouch

    [_cat moveToward:touchLocation];
}

FIXED CODE HERE - THIS ALSO FIXES INVERTED Y AXIS

CGPoint touchLocation = [[CCDirector sharedDirector] convertToGL:[self convertToNodeSpace:[tapRecognizer locationInView:[[CCDirector sharedDirector] openGLView]]]];
shim
  • 9,289
  • 12
  • 69
  • 108
Oscar Apeland
  • 6,422
  • 7
  • 44
  • 92

4 Answers4

96

You can use the locationInView: method on UIGestureRecognizer. If you pass nil for the view, this method will return the location of the touch in the window.

- (void)handleTap:(UITapGestureRecognizer *)tapRecognizer
{
    CGPoint touchPoint = [tapRecognizer locationInView: _tileMap]
}

There is also a helpful delegate method gestureRecognizer:shouldReceiveTouch:. Just make sure to implement and set your tap gesture's delegate to self.

Keep a reference to the gesture recognizer.

@property UITapGestureRecognizer *theTapRecognizer;

Initiailze the gesture recognizer

_theTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(someMethod:)];
_theTapRecognizer.delegate = self;
[someView addGestureRecognizer: _theTapRecognizer];

Listen for delegate methods.

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    CGPoint touchLocation = [_tileMap convertTouchToNodeSpace: touch];
    // use your CGPoint
    return YES;
}
MJN
  • 10,748
  • 1
  • 23
  • 32
  • I need an UITouch for my `CGPoint touchLocation = [_tileMap convertTouchToNodeSpace:locationOfTap];` Where convertTouchToNodeSpace converts a UITouch.. Can this code be used in that way? – Oscar Apeland May 17 '13 at 21:31
  • Could you just modify `convertTouchToNodeSpace:` method to take in a CGPoint? – MJN May 17 '13 at 21:39
  • I can't find out where its defined, hahaha – Oscar Apeland May 17 '13 at 21:40
  • Command click on the method name. Or is it in a private framework? – MJN May 17 '13 at 21:40
  • No, its cocos2d, open source as it gets. – Oscar Apeland May 17 '13 at 21:41
  • `- (CGPoint)convertTouchToNodeSpace:(UITouch *)touch { CGPoint point = [touch locationInView: [touch view]]; point = [[CCDirector sharedDirector] convertToGL: point]; return [self convertToNodeSpace:point]; } ` It does not get happy when I change it to CGPoint – Oscar Apeland May 17 '13 at 21:43
  • I tried that, how do I properly set the delegate to self? I declare it like this: `self.tapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)] autorelease]; [_tapRecognizer requireGestureRecognizerToFail:_doubleTapRecognizer]; [[[CCDirector sharedDirector] openGLView] addGestureRecognizer:_tapRecognizer];` – Oscar Apeland May 17 '13 at 21:57
  • You'll need to keep a reference to the gesture recognizer as a property or an instance variable. – MJN May 17 '13 at 22:13
  • Seems like I can actually pass a CGpoint with `CGPoint location = [tapRecognizer locationInView:[[CCDirector sharedDirector] openGLView]];` directly to moveToward, and that the glitch is somewhere else.. :s Will accept your answer anyways, as it helped me. – Oscar Apeland May 17 '13 at 22:22
17

In Swift:

func handleFrontTap(gestureRecognizer: UITapGestureRecognizer) {
   print("tap working")
   if gestureRecognizer.state == UIGestureRecognizerState.Recognized
   { 
      print(gestureRecognizer.locationInView(gestureRecognizer.view))
   }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
user3108511
  • 209
  • 2
  • 7
1

Try this:

-(void) didMoveToView:(SKView *)view{
    oneFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(oneTapDetected:)];
    oneFingerTap.numberOfTapsRequired=1;
    oneFingerTap.numberOfTouchesRequired=1;

    [view addGestureRecognizer:oneFingerTap];
}

-(void)oneTapDetected:(UITapGestureRecognizer *)recognizer{
    NSLog(@"one tap detec");
    tapPositionOneFingerTap = [oneFingerTap locationInView:self.view];
    NSLog(@"%f, %f",tapPositionOneFingerTap.x,tapPositionOneFingerTap.y);
}

This prints the coordinates of each tap in your console.

Pang
  • 9,564
  • 146
  • 81
  • 122
0

Apple Docs say

UIGestureRecognizer

- (NSUInteger)numberOfTouches

The number of UITouch objects in a private array maintained by the receiver.

So you shouldn't access them.

Using the value returned by this method in a loop, you can ask for the location of individual touches using the locationOfTouch:inView: method.

Pang
  • 9,564
  • 146
  • 81
  • 122