0

I have created a game where the main menu is contained within a normal ViewController and the actual game is played within an SKScene.

I use a modal segue from a button on the main menu to open the SKScene.

The problem I get is when I try to return from the SKScene to the main menu.

I'm using this code to present the main menu

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)

            if homeBtn.containsPoint(location)
            {
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                let settingController: UIViewController = storyboard.instantiateViewControllerWithIdentifier("homeViewController") as UIViewController

                let vc = self.view?.window?.rootViewController
                vc?.presentViewController(settingController, animated: true, completion: nil)

            }
        }
    }

However this causes the following message:

Warning: Attempt to present ViewController on ViewController whose view is not in the window hiearchy!

CodeSmile
  • 64,284
  • 20
  • 132
  • 217

1 Answers1

0

Your Scene should not call back to the ViewController. It creates too much dependence between the View and the ViewController.

Here is how I use the delegate in Objective-C (sorry I don't know swift). Here are some examples in Swift.

// GameViewController.h
@interface GameViewController : UIViewController <GameSceneDelegate>


// GameViewController.m
// where we setup new scenes. Don't forget this.
newScene.delegate = self;

-(void)displayMenu {
    ... setup and display the menu
}

Create a simple delegate class

// GameSceneDelegate.m
@protocol GameSceneDelegate <NSObject>
-(void)displayMenu;
@end

Your game scene now keeps a reference to the delegate. Other ViewControllers can now use your GameScene without backward references.

// GameScene.h
@interface GameScene : SKScene
@property (assign) id<GameSceneDelegate> gameSceneController;


// GameScene.m
[self.gameSceneController displayMenu];

Other ways you can get the message back to the GameViewController is using an NSController, but this is a bit messy. Or you could also consider something like Reactive Cocoa.

Community
  • 1
  • 1
Patrick Collins
  • 4,046
  • 3
  • 26
  • 29