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?