Reputation: 363
There seems to be so many contradicting ideas on this topic. I simply wish to have my menu in a UIViewController and my game in the SKScene
In my SKScene I used:
self.removeFromParent()
self.view?.presentScene(nil)
The nodes are removed but the scene is still in place as I still have the grey background and fps counter. Can I return to the View aspect of the UIViewController and hide the scene?
My method one implementation:
RootViewController:
class RootViewController: UIViewController {
var menu = MenuViewController()
var game = GameViewController()
override func viewDidLoad() {
super.viewDidLoad()
print("root")
MenuPresent()
}
func GamePresent() {
self.addChildViewController(game)
self.view.addSubview((game.view)!)
game.didMoveToParentViewController(self)
}
func MenuPresent() {
self.addChildViewController(menu)
self.view.addSubview((menu.view)!)
menu.didMoveToParentViewController(self)
}
func menuDismiss() {
menu.willMoveToParentViewController(nil)
menu.removeFromParentViewController()
menu.view.removeFromSuperview()
}
}
MenuViewController:
class MenuViewController: UIViewController {
//var root = RootViewController()
override func viewDidLoad() {
super.viewDidLoad()
print("menu")
}
}
The print("menu") appears in my console, But the actual view and all assets of the MenuViewController do no appear.
On the other hand my GameViewController and it's SKScene work fine.
Upvotes: 0
Views: 609
Reputation: 687
First you need to know that SKScene
and UIViewController
are totally two different things. The hierarchy is typically as following:
UIViewController
--> UIView
(SKView
) --> SKScene
So you SKScene
is presented in a SKView
which can be a UIView
, then the UIView
is presented in a UIViewController
.
Once you know the hierarchy, everything is easy. There are many ways to use different UIViewController
for menu and GameScene
stuff.
Method One
For example, you can have a RootViewController
, a GameViewController
and a MenuViewController
. The RootViewController
is the initial ViewController when the app launches.
In the RootViewController
, you can create a function to present the GameViewController
:
func setupGameViewController() {
self.gameViewController = GameViewController()
self.addChildViewController(gameViewController!)
self.view.addSubview((gameViewController!.view)!)
gameViewController?.didMoveToParentViewController(self)
}
You need to present you SKScene
in GameViewController
, I guess you should be familiar with this step.
Then when you need to display the menu, you can add the MenuViewController
to RootViewController
with a function like:
func setupMenuViewController() {
self.menuViewController = MenuViewController()
self.addChildViewController(menuViewController!)
self.view.addSubview((menuViewController!.view)!)
menuViewController?.didMoveToParentViewController(self)
}
You also need to present you menuView in this ViewController, which I suppose you already know.
Also create a function to dismiss the MenuViewController
:
func removeMenuViewController(){
self.menuViewController?.willMoveToParentViewController(nil)
self.menuViewController?.removeFromParentViewController()
self.menuViewController?.view.removeFromSuperview()
}
And everything is done.
Method Two
You can also have only one UIViewController
, but create you menu as a UIView
, then you can use self.view.addSuview(menuView)
to present your menu. Of course you root view, which is the self.view as SKView
is still there, but it doesn't matter because it's hidden behind the menuView
.
A Note for your updated question
You cannot remove the scene because the scene is actually self.view as SKView
, self.view
is the root view of a UIViewController, it cannot be removed. If you really want to remove you scene (for most cases, it's not necessary), you can create a new SKView
that present your SKScene
, then add this SKView
to your UIViewController
by self.view.addSubview(skView)
, when you want to completely remove the scene, just use skView.removeFromSuperview()
.
Upvotes: 1
Reputation: 1025
Views and scenes are two different things. Scenes are held inside of a view. You would have to simply present a scene within your menu view or transition to another view and present an SKScene from there. The code to present the scene might look like this:
let scene = GameScene(fileNamed: "GameScene")
let skView = self.view as! SKView
scene?.scaleMode = .AspectFit
skView.presentScene(scene)
Upvotes: 2