All I want if for when the user touches a skspritenode in the skscene, it will go to a different view like performseguewithidentifier
. Thanks for any help. I ca
You cannot present a viewController from within a SKScene as it is actually only being rendered on a SKView. You need a way to send a message to the SKView's viewController, which in turn will present the viewController. For this, you can use delegation or NSNotificationCenter.
Delegation
Add the following protocol definition to your SKScene's .h file:
@protocol sceneDelegate <NSObject>
-(void)showDifferentView;
@end
And declare a delegate property in the interface:
@property (weak, nonatomic) id <sceneDelegate> delegate;
Then, at the point where you want to present the share screen, use this line:
[self.delegate showDifferentView];
Now, in your viewController's .h file, implement the protocol:
@interface ViewController : UIViewController <sceneDelegate>
And, in your .m file, add the following line before you present the scene:
scene.delegate = self;
Then add the following method there:
-(void)showDifferentView
{
[self performSegueWithIdentifier:@"whateverIdentifier"];
}
NSNotificationCenter
Keep the -showDifferentView method as described in the previous alternative.
Add the viewController as a listener to the notification in it's -viewDidLoad method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showDifferentView) name:@"showDifferenView" object:nil];
Then, in the scene at the point where you want to show this viewController, use this line:
[[NSNotificationCenter defaultCenter] postNotificationName:@"showDifferentView" object:nil];
ZeMoon, nice answer, but what if multiple scenes want to show the same view controller, for example some settings screen? You don't want to define multiple scene delegate protocols that do the same thing.
Another idea is to define a single protocol which handles the presentation of different view controllers for you:
@protocol ScreenFlowController <NSObject>
- (void)presentSettingsScreenFromScene:(SKScene *)scene;
- (void)presentCreditsScreenFromScene:(SKScene *)scene;
@end
The scene parameter might be used to make decisions based on where you are coming from.
The view controller of your game (or any other object) implements the protocol. All scenes that display a different screen receive a weak reference to the controller:
@property (nonatomic, weak) id<ScreenFlowController> screenFlowController;
I suggest the following option: (this goes in your scene)
-(void)presentViewController{
MyViewController *myController = [[MyViewController alloc]init];
//Or instantiate any controller from the storyboard with an indentifier
[self.view.window.rootViewController presentViewController:myController animated: YES options: nil];
}
And later in your view controller, when you wish to dismiss it, do something like this:
-(void)dismissItself:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
The good thing about this option is that you won't need to store your view since at any point you can initialize it as long as the scene you are in, imports the viewcontroller's code.
Let me know if it works