Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I notify incoming scene when presentScene:transition: is complete?

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?

like image 800
jemmons Avatar asked Nov 24 '13 22:11

jemmons


2 Answers

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.

like image 111
jemmons Avatar answered Oct 23 '22 12:10

jemmons


Perform selector after delay with the same delay as the transition is perfectly reasonable.

like image 37
LearnCocos2D Avatar answered Oct 23 '22 11:10

LearnCocos2D