1

I have a drawing simulation SKScene that works fine in iOS 7 that doesn't work in iOS 8. This is both for the simulator and the device.

The scene should show black lines where the finger touches the screen, and they should persist after you have finished "drawing" a line. Here's a screenshot of it in iOS 7:

enter image description here

Although there are no crashes, the lines don't render at all in iOS 8. I just get a blank canvas. NSLogging indicates that it does register the touchesBegan/Moved/Ended functions correctly.

I have produced the entire class in its entirety:

@implementation CSDraw

-(id)initWithSize:(CGSize)size type:(NSString *)CSType stresslevel:(NSInteger)stress_indicator { //designated initializer
    if (self = [super initWithSize:size type: CSType stresslevel:stress_indicator]) {
        NSLog(@"Creating new scene from CSDraw within the init");
    }
    return self;
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    self.swiped = NO;
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    self.pathToDraw = CGPathCreateMutable();

    CGPathMoveToPoint(self.pathToDraw, NULL, positionInScene.x, positionInScene.y);

    self.lineNode = [SKShapeNode node];
    self.lineNode.path = self.pathToDraw;
    self.lineNode.strokeColor = [SKColor blackColor];
    self.lineNode.lineWidth = 10;
    self.lineNode.zPosition = 50;

    [self addChild:self.lineNode];

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    self.swiped = YES;
    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    CGPathAddLineToPoint(self.pathToDraw, NULL, positionInScene.x, positionInScene.y);
    self.lineNode.path = self.pathToDraw;

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    if(!self.swiped) { //user just tapped once, draw a single point
        SKSpriteNode *dot = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(10, 10)];
        dot.position = positionInScene;
        [self addChild: dot];

    } else { //calls touchesMoved
    }

    //[self.lineNode removeFromParent]; //comment out this line if you want line to remain on screen
    CGPathRelease(self.pathToDraw);
}
@end

This class was written from the code I found in this StackOverFlow answer.

Community
  • 1
  • 1
Iris Z.
  • 13
  • 4

1 Answers1

0

I had a similar problem with a Sprite Kit iOS8 game and fixed it with something like this: Try adding a CGPathMoveToPoint call immediately before the CGPathAddLineToPoint call in your touchesMoved function.

According to the class reference for CGPathAddLineToPoint, calling CGPathAddLineToPoint automatically "updates the current point to the specified location (x,y) [the new endpoint]". However, my lines weren't getting rendered correctly in iOS8 until I did this manually by calling CGPathMoveToPoint before every CGPathAddLineToPoint call. Not sure why this is. Maybe a bug with Sprite Kit in iOS8.

Please find below the modified code, with changes marked with a /* new */ comment. The code assumes that you have a CGPoint property called lastPointTouched.

 @implementation CSDraw

-(id)initWithSize:(CGSize)size type:(NSString *)CSType stresslevel:(NSInteger)stress_indicator { //designated initializer
    if (self = [super initWithSize:size type: CSType stresslevel:stress_indicator]) {
        NSLog(@"Creating new scene from CSDraw within the init");
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    self.swiped = NO;
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    self.pathToDraw = CGPathCreateMutable();

    CGPathMoveToPoint(self.pathToDraw, NULL, positionInScene.x, positionInScene.y);
    /* new */ self.lastPointTouched = positionInScene; 

    self.lineNode = [SKShapeNode node];
    self.lineNode.path = self.pathToDraw;
    self.lineNode.strokeColor = [SKColor blackColor];
    self.lineNode.lineWidth = 10;
    self.lineNode.zPosition = 50;

    [self addChild:self.lineNode];

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    self.swiped = YES;
    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    /* new */ CGPathMoveToPoint(self.pathToDraw, NULL, self.lastPointTouched.x, self.lastPointTouched.y);
    CGPathAddLineToPoint(self.pathToDraw, NULL, positionInScene.x, positionInScene.y);
    /* new */ self.lastPointTouched = positionInScene;
    self.lineNode.path = self.pathToDraw;

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    if(!self.swiped) { //user just tapped once, draw a single point
        SKSpriteNode *dot = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(10, 10)];
        dot.position = positionInScene;
        [self addChild: dot];

    } else { //calls touchesMoved
    }

    //[self.lineNode removeFromParent]; //comment out this line if you want line to remain on screen
    CGPathRelease(self.pathToDraw);
}
@end
jj080808
  • 148
  • 1
  • 6