Let's say I'm transitioning from an old SKScene
of an SKView
to a new one:
//In some controller somewhere...
-(void)swapScenes{
MySceneSubclass *newScene = [[MySceneSubclass alloc] initWithSize:CGSizeMake(1024, 768)];
SKTransition *transition = [SKTransition crossFadeWithDuration:REALLY_LONG_DURATION];
[[self mySKView] presentScene:newScene transition:transition];
}
Let's additionally say I want my new scene to perform some action or animation once the transition is completed, but not before. What would I use to trigger that?
At first I thought I'd be able to override didMoveToView:
to do this, but it turns out this is called at the very begining of the transition (in hindsight, this makes sense. In a crossfade, the incoming scene is composited at the very beginning of the animation, even if its opacity is very low).
Next, as a hail mary, I tried inserting a call to the new scene right after presentScene
:
-(void)swapScenes{
MySceneSubclass *newScene = [[MySceneSubclass alloc] initWithSize:CGSizeMake(1024, 768)];
SKTransition *transition = [SKTransition crossFadeWithDuration:REALLY_LONG_DURATION];
[[self mySKView] presentScene:newScene transition:transition];
[newScene doSomethingAfterTransition]; //<----
}
But presentScene:
predictably returned immediately causing this method to be called long before the transition had completed.
As a last resort, I'm considering something like:
[newScene performSelector:@selector(doSomethingAfterTransition) afterDelay:REALLY_LONG_DURATION];
But I'd really like to avoid that if at all possible. It seems like there ought to be an delegate action or notification or something that knows when the transition is over, right?
The answer to this was staring me in the face. As I mentioned above, in a transition both scenes need to be present throughout the animation. Thus the incoming scene's didMoveToView:
is called immediately at the beginning of the transition instead of at the end as I expected.
Of course, by this same logic, the outgoing scene's willMoveFromView:
won't get called until the end of the transition. Which is what I was looking for in the first place.
So, you can override -willMoveFromView:
of the outgoing scene (or, more likely, some shared superclass) to send a notification or call a delegate or whatever you like when transition completes. In my case, I have it call a block so I can keep everything local to my -swapScenes
method, but YMMV.
Perform selector after delay with the same delay as the transition is perfectly reasonable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With