Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITapGestureRecognizer on SKNode: Converting Coordinates from UIView to SKNode

I have a UITapGestureRecognizer and a UIPanGestureRecognizer on a UIView with a SKScene on it. The pan gesture recogniser moves a SKNode left to right, and I want the Tap gesture recogniser to detect a child of the SKNode that pans. Panning works fine, but I'm having trouble detecting taps - the Tap Gesture fires the relevant method, but I'm not sure how to convert the coordinates from the view to the scene to the node to detect if the tap is in one of the children nodes.

UIView (with gestures) → SKScene → Panning node → Children of panning node

How do I check a whether a tap gesture's touch coordinate is any given SKNode?

-(void)tapAction:(UITapGestureRecognizer*)sender{
if (sender.state == UIGestureRecognizerStateEnded)
{
    // handling code
    CGPoint touchLocation = [sender locationOfTouch:0 inView:sender.view];
    NSLog(@"TAP %@", NSStringFromCGPoint(touchLocation)
          );
    for (SKLabelNode *node in _containerNode.children) {

        if ([node containsPoint:[node convertPoint:touchLocation fromNode:self.parent]]) {
            //This is where I want the tap to be detected.
        }

        CGPoint checkPoint = [node convertPoint:touchLocation fromNode:self.scene];
        NSLog(@"CheckPoint %@", NSStringFromCGPoint(checkPoint)
              );
        //NSLog(@"iterating nodes");
        if ([node containsPoint:checkPoint]) {
            NSLog(@"touch match %@", node);

        }
    }
}

}

like image 411
glenstorey Avatar asked Mar 17 '15 22:03

glenstorey


2 Answers

In the end I needed to do a couple more steps from what were suggested - converting from the SKView → SKScene and then to the SKNode which contained the nodes I was hit testing.

    CGPoint touchLocation           = [sender locationOfTouch:0 inView:sender.view];
    CGPoint touchLocationInScene    = [[self.scene view] convertPoint:touchLocation toScene:self.scene];
    CGPoint touchLocationInNode     = [self.scene convertPoint:touchLocationInScene toNode:_containerNode];
like image 149
glenstorey Avatar answered Sep 22 '22 10:09

glenstorey


You should convert the View coordinates to Scene Coordinates using convertPointFromView:

CGPoint touchLocationInView = [sender locationOfTouch:0 inView:sender.view];
CGPoint touchLocationInScene = [self convertPointFromView:touchLocationInView];

Then you can detect which label node was tapped using,

for (SKLabelNode *node in self.children) {

    if ([node containsPoint:touchLocationInScene]) {
        //This is where I want the tap to be detected.
    }

}
like image 28
rakeshbs Avatar answered Sep 22 '22 10:09

rakeshbs