How to reference the current Viewcontroller from a Sprite Kit Scene

ios, reference, skscene, sprite-kit, viewcontroller

Solution

A better option than my "back reference" answer is to use a protocol to explicitly define the methods that a `SKScene` subclass expects the `UIViewController` subclass to implement. Here are the steps you'll need to go through.

1) Define the protocol (contract) that the `UIViewController` will need to adopt and conform to:

protocol GameManager{
    func loadHomeScene()
    func loadGameScene(level:Int)
    func loadHighScoreScene()
}

2) The `UIViewController` subclass now adopts the protocol:

`class GameViewController: UIViewController,GameManager{`

3) The `GameScene` gets an ivar that references the `UIViewController`:

`var gameManager:GameManager?`

4) When the `GameManager` needs to call the `UIViewController`, it does so like this:

`gameManager.loadHighScoreScene()`

We now have a well-defined contract of what a `GameManager` is. Any other developers (and the current developer's future self) that work on this project now know which methods a `GameManager` should implement. This means we could easily port this code to a different project (and thus a different `UIViewController`) and it would still work as long as this new `UIViewController` adopted the `GameManager` protocol.

Similarly, if we decided to move our scene navigation code out of the view controller, and instead placed it in a singleton class, this singleton class would merely need to adopt the `GameManager` protocol.

Which approach to use?

This thread gives 4 approaches to solving the problem, and I have personally used all 4. Here's my take on them:

1) Hard-coding a call to the `UIViewController` subclass:

`(self.view!.window!.rootViewController as! GameViewController).loadGameScene(1)`

Advantage: 1 line of code!

Disadvantage: A very tight coupling of 2 classes, without an explicit contract.

2) Using a pointer back to the `UIViewController`:

Advantages: Very little code required, No protocol required.

Disadvantages: Tight coupling of 2 classes. No explicit contract.

3) Using `NSNotificationCenter`:

Advantage: Loosely coupled classes.

Disadvantages: more code needed to set up the broadcaster, receiver, and callback methods. Harder to trace and debug the code. No explicit contract. The "one-to many" capability of notifications is nice, but doesn't help us here.

4) Creating a protocol:

Advantages: An explicit contract. The gods of MVC will be pleased.

Disadvantage: More code to write (but much less than notifications).

Problem

I'm having a hard time finding the answer to this question I assume is not that hard. How can I reference methods and properties defined on a viewcontroller from a SKScene ? And building on that: How can you reference the ViewController from a SKScene that was loaded from within another SKScene?

Original source