I've come to the point where I need to make a start screen for my game made with sprite kit. I can not get it to show with any of the code and tutorials I have read and watched.
I want to use a navigation controller/view controller to begin at the start screen and have it linked to my app but I am not sure how to link my game's code to the view controller.
Using a navigation controller, how would I drag it into my game's code as a #IBAction declaration? Thank you.
Edit with current code:
ViewController.m:
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
scene.viewController = self;
[skView presentScene:scene];
}
MyScene.h:
#interface MyScene : SKScene <SKPhysicsContactDelegate>
#property (strong, nonatomic) UIViewController *viewController;
#end
This answer is based on the one here, but has been translated to Objective-C.
The problem that you are facing is that an SKScene does not have direct access to it's viewController, but just the view in which it is contained. You need to create a pointer to it manually. This can be done by creating a property for the SKScene:
#interface GameScene : SKScene
#property (strong, nonatomic) UIViewController *viewController;
#end
Then, in the viewController class, just before [skView presentScene:scene];
scene.viewController = self;
Now, you can access the viewController directly. Simply call the segue on this viewController:
-(void)goToHomeScreen {
[self.viewController.navigationController popToRootViewControllerAnimated:YES];
}
You can perform other navigationController operations in a similar way.
Related
My situation is that I have a GameMenuScene and after the user chooses a level, I want to present the LevelScene. But I do not want to have the previous GameMenuScene discarded because the LevelScene is actually a #property of GameMenuScene and whether or not the user completes the level is to be saved as a #property of LevelScene, which the GameMenuScene should be able to access after the user finishes or exits the level. If I simply use presentScene:transition, the GameMenuScene is discarded and the information cannot pass back.
My question: Is there a way to stack or push the scenes on top of each other without discarding the previous (preferably using a transition animation)? I could not find a method for this specific purpose in the Apple Documentation for SKScene.
Note: Another StackOverflow answer to a similar question suggests to create a new UIViewController, present the LevelScene in there and then present the UIViewController modally. But I was hoping there was an existing method in the Apple Documentation that I have missed to present the scene itself scene modally without having to create UIVIewControllers.
There is no navigation controller-like capability for SKScenes that allows you to push and pop scenes. You will need to write code to manage and present your scenes.
Here's a simple view controller implementation that allows you to switch between two scenes (by swiping) without discarding the other scene.
#interface ViewController()
#property BOOL viewFlag;
#property SKScene *scene1;
#property SKScene *scene2;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeGesture];
// Create and configure scene 1.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
self.scene1 = scene;
// Present the scene 1.
[skView presentScene:scene];
// Create and configure scene 2.
scene = [MySecondScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
self.scene2 = scene;
}
- (void) handleSwipeGesture:(id)sender
{
SKView * skView = (SKView *)self.view;
_viewFlag = !_viewFlag;
if (_viewFlag) {
[skView presentScene:_scene1];
}
else {
[skView presentScene:_scene2];
}
}
#end
I'm using Sprite kit framework to create a game.
My first scene is MyScene.My Scene is a menu, but i want when is clicked on start to switch to the first view from the story board.
This is the way i switch to another SKScene
Scene001 *start = [[Scene001 alloc] initWithSize:self.size];
SKTransition *reveal = [SKTransition fadeWithColor:[UIColor clearColor] duration:0.5];
[self.scene.view presentScene: start transition: reveal];
Now the question is how to switch to the storyboard scene and vice versa.
I know this is old but just incase someone comes across it and needs an answer:
What I did in my game was make my GameViewController be a delegate of the SKScene. When the user is finished in the SKScene, I called my delegate function in the GameViewController which simply does a performSegueWithIdentifier.
Your viewController that creates your scene has can run segue's. So you need a way to get back to it from your SKScene. Simply make your SKScene a delegate and when your viewController creates it, set the delegate. Then when you want to switch, call the delegate function.
This is my GameViewController that creates my scene:
- (void)viewWillAppear:(BOOL)animated {
SKView * skView = (SKView *)self.view;
if (!skView.scene) {
MyScene *scene = [MyScene sceneWithSize:self.view.bounds.size];
scene.delegate = self;
[skView presentScene:scene];
}
}
// A delegate function
- (void)onExitGame {
[self performSegueWithIdentifier:#"GoToNextScene" sender:self];
}
Then from my MyScene when you're ready to switch the storyboard call the delegate function:
if (self.delegate) {
self.delegate.onExitGame();
}
P.S: Please do not suggest me to go with the app delegate way as I will use that in the middle of my app views. Thanx.
I try to use a UINavigationController to display a UITableView like the settings app. So I am trying to start step by step. So far, I try to show up a view contained in a view controller in the navigation stack. But I am missing something somewhere.
Here is my relevant code:
.h file:
#interface ViewController : UINavigationController{
UINavigationController *navigationController;
UIViewController *viewController;
}
#property(nonatomic, strong)IBOutlet UINavigationController *navigationController;
#property(nonatomic, strong)IBOutlet UIViewController *viewController;
#end
.m file :
#implementation ViewController
#synthesize navigationController;
#synthesize viewController;
- (void)viewDidLoad
{
[super viewDidLoad];
//Do any additional setup after loading the view, typically from a nib.
self.viewController = [[UIViewController alloc]init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.navigationController.view addSubview:self.viewController.view];
}
**The xib file:**
When I run the app, I am expecting to see the blue view, but all I see is the default blue navigation bar, without even the "Root View Controller" title message.
If you connect UI from IB, try to delete these line (delete alloc, init)
// self.viewController = [[UIViewController alloc]init];
// self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
// [self.navigationController.view addSubview:self.viewController.view];
This link Should help you. You might want to go through this to shed better light on the problem you're having.
https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/SecondiOSAppTutorial/Introduction/Introduction.html
I am trying to create a view which contains three subview having different view controller (UICollectionViewController,pageviewcontroller and uiviewcontroller).
i am able to add a uiviewcontroller but other two controller is not allowed.
I am getting this error.....
Incompatible pointer types sending 'UICollectionView *__weak' to parameter of type 'UIViewController *'
Is their any way to add these controller to my subview?
I don't know why you want to add ViewControllers inside a view, i never need it.
I tried to do that, if can help you this is my running code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, retain) UICollectionViewController *collectionViewController;
#property (nonatomic, retain) UIPageViewController *pageViewController;
#property (nonatomic, retain) UIViewController *simpleViewController;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize collectionViewController;
#synthesize pageViewController;
#synthesize simpleViewController;
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];
collectionViewController = [[UICollectionViewController alloc] initWithCollectionViewLayout:layout];
pageViewController = [[UIPageViewController alloc] init];
simpleViewController = [[UIViewController alloc] init];
// Do your stuff with this controllers
[self.view addSubview:collectionViewController.view];
[self.view addSubview:pageViewController.view];
[self.view addSubview:simpleViewController.view];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You don't add view controllers to views. You add views to views (as subviews) and, much more rarely, controllers to controllers (as child controllers).
Think of them as two parallel hierarchies: Given ControllerA that controls view ViewA, you want to make ControllerB a child controller of ControllerA such that it's view, ViewB is a subview of ViewA.
See the WWDC 2011 video: "Implementing UIViewController Containment"
I have a UIViewController calling another view Controller with a defined loadView method. I’ve been trying many options without success to solve the problem of the loadView method not called.
Any help is appreciated.
Thanks.
MArcos
Caller UIViewController
#import "MyAlbumViewController.h"
#interface ViewController : UIViewController
#end
implementation
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated{
UIViewController*albumVC = [[MyAlbumViewController alloc] init];
[self.navigationController pushViewController:albumVC animated:YES];
}
#end
Called UIViewController
#interface MyAlbumViewController : NIToolbarPhotoViewController <NIPhotoAlbumScrollViewDataSource>
#end
Implementation
#import "MyAlbumViewController.h"
#implementation MyAlbumViewController
- (void)loadView{
[super loadView];
self.photoAlbumView.dataSource = self;
// Set the default loading image.
self.photoAlbumView.loadingImage = [UIImage imageWithContentsOfFile:
NIPathForBundleResource(nil, #"NimbusPhotos.bundle/gfx/default.png")];
self.title = NSLocalizedString(#"Loading...", #"Navigation bar title - Loading a photo album");
[self loadAlbumInformation];
}...
The idea of loadView is to completely override the method, and not call super
What you are doing is exactly what the viewDidLoad method is for, it doesn't matter if you loaded it from a nib file or whatever
And I quote from your own post, in your ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
I was pushing view controller with:
[self.navigationController pushViewController:albumVC animated:YES];
I just changed to:
[self presentViewController:albumVC animated:YES completion:nil];
UIViewController Navigation Controller
navigationController The nearest ancestor in the view controller
hierarchy that is a navigation controller. (read-only)
#property(nonatomic, readonly, retain) UINavigationController
*navigationController Discussion If the receiver or one of its ancestors is a child of a navigation controller, this property
contains the owning navigation controller. This property is nil if the
view controller is not embedded inside a navigation controller.