Question

I am trying to create a UIRotationGestureRecognizer in an SKScene, and add it to the scenes view. When I add the gesture to the view, I assign it's target to the scene and the action to a method in the scene. The scene's method never gets called, and the gesture recognizer's view property is always NULL.

//
//  MyScene.h
//  Rotate SpaceShip
//

//  Copyright (c) 2014 Andrew Paterson. All rights reserved.
//

#import <SpriteKit/SpriteKit.h>

@interface MyScene : SKScene <UIGestureRecognizerDelegate>

@end

The Implementation:

//
//  MyScene.m
//  Rotate SpaceShip
//
//  Created by Andrew Paterson on 2/23/14.
//  Copyright (c) 2014 Andrew Paterson. All rights reserved.
//

#import "MyScene.h"
@interface MyScene ()
@property (strong, nonatomic)UIRotationGestureRecognizer *rotationGestureRecognizer;
@end
@implementation MyScene

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */

        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];

        SKSpriteNode *spaceShip = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        spaceShip.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
        spaceShip.name = @"spaceship";

        [self addChild:spaceShip];

        self.rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc]
                                          initWithTarget:self
                                          action:@selector(handleRotation:)];
        self.rotationGestureRecognizer.delegate = self;
        [self.view addGestureRecognizer:self.rotationGestureRecognizer];
    }
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    [super touchesBegan:touches withEvent:event];

}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}
- (void)moveFromScene{
    [self.view removeGestureRecognizer:self.rotationGestureRecognizer];
}
- (void)handleRotation:(UIRotationGestureRecognizer *)recognizer{
    SKSpriteNode *spaceship = (SKSpriteNode *)[self childNodeWithName:@"spaceship"];
    if (!(recognizer.state == UIGestureRecognizerStateEnded)){

    spaceship.zRotation =  (spaceship.zRotation + (recognizer.rotation - spaceship.zRotation));

    }

}
@end

The debugger outputs this when I break at update and print the gesture recognizer

(lldb) po self.rotationGestureRecognizer.view
 nil
(lldb) po self.rotationGestureRecognizer
<UIRotationGestureRecognizer: 0xa04d570; state = Possible; view = <(null) 0x0>; target= <(action=handleRotation:, target=<MyScene 0x9632380>)>>
(lldb) 

Any help with solving this very weird problem would be greatly appreciated.

Was it helpful?

Solution

Apparently there is a bug in sprite kit that causes this issues when adding a gesture recognizer in initWithSize: If you move it to didMoveToView: the problem goes away.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top