Skip to content

Instantly share code, notes, and snippets.

@coreyroach
Created November 6, 2013 23:28
Show Gist options
  • Save coreyroach/7346103 to your computer and use it in GitHub Desktop.
Save coreyroach/7346103 to your computer and use it in GitHub Desktop.
This is a quick and simple SpriteKit scene stack. Similar to a UINavigationController, this helps to manage navigating from one scene to the next and back by pushing or popping scenes from the stack.
// Configure the view.
SKStackView *skView = (SKStackView *)self.view;
skView.transitionDuration = 0.5;
skView.pushTransition = [SKTransition doorsOpenVerticalWithDuration:skView.transitionDuration];
skView.popTransition = [SKTransition doorsCloseVerticalWithDuration:skView.transitionDuration];
// Create and configure the scene.
SKScene *scene = [SKScene sceneWithSize:skView.bounds.size];
// Present the scene.
[skView pushSceneToStack:scene transition:YES];
/**
* Remove a scene from the stack
**/
[skView popSceneFromStackTransition:YES];
#import <SpriteKit/SpriteKit.h>
@interface SKStackView : SKView
@property (nonatomic, strong) NSArray *scenes;
@property (nonatomic, strong) SKTransition *pushTransition;
@property (nonatomic, strong) SKTransition *popTransition;
@property (nonatomic) SKSceneScaleMode defaultScaleMode;
@property (nonatomic) CGFloat transitionDuration;
@property (nonatomic) BOOL useDefaultScaleMode;
@property (nonatomic, strong) UIButton *backButton;
- (void)pushSceneToStack:(SKScene*)scene transition:(BOOL)transition;
- (void)popSceneFromStackTransition:(BOOL)transition;
@end
#import "SKStackView.h"
@implementation SKStackView
@synthesize defaultScaleMode = _defaultScaleMode;
@synthesize pushTransition = _pushTransition;
@synthesize popTransition = _popTransition;
@synthesize transitionDuration = _transitionDuration;
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
_scenes = [NSArray array];
_useDefaultScaleMode = YES;
}
return self;
}
- (void)pushSceneToStack:(SKScene *)scene transition:(BOOL)transition {
if (self.useDefaultScaleMode) scene.scaleMode = self.defaultScaleMode;
NSMutableArray *arr = self.scenes.mutableCopy;
[arr addObject:scene];
self.scenes = arr.copy;
[self presentScene:scene transition:transition ? self.pushTransition : nil];
}
- (void)popSceneFromStackTransition:(BOOL)transition {
NSMutableArray *arr = self.scenes.mutableCopy;
[arr removeLastObject];
self.scenes = arr.copy;
[self presentScene:(SKScene*)[self.scenes lastObject] transition:transition ? self.popTransition : nil];
}
#pragma mark - Private Methods
- (void)presentScene:(SKScene *)scene withTransition:(SKTransition*)transition {
SEL action = transition ? @selector(presentScene:transition:) : @selector(presentScene:);
if ([self respondsToSelector:action]) {
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:action]];
[inv setSelector:action];
[inv setTarget:self];
[inv setArgument:&(scene) atIndex:2];
if (transition) [inv setArgument:&(transition) atIndex:3];
[inv invoke];
}
}
#pragma mark - Lazy Instantiation
- (SKSceneScaleMode)defaultScaleMode {
if (!_defaultScaleMode)
_defaultScaleMode = SKSceneScaleModeAspectFill;
return _defaultScaleMode;
}
- (SKTransition *)pushTransition {
if (!_pushTransition)
_pushTransition = [SKTransition fadeWithDuration:self.transitionDuration];
return _pushTransition;
}
- (SKTransition *)popTransition {
if (!_popTransition)
_popTransition = [SKTransition fadeWithDuration:self.transitionDuration];
return _popTransition;
}
- (CGFloat)transitionDuration {
if (!_transitionDuration)
_transitionDuration = 1.0;
return _transitionDuration;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment