How to dismiss the current ViewController and go to another View in Swift
Asked Answered
P

2

15

I am new to Swift and I want to know how to dismiss the current view controller and go to another view.

My storyboard is like the following: MainMenuView -> GameViewController -> GameOverView. I want to dismiss the GameViewController to go to the GameOverView, not to the MainMenuView.

I use the following code in my MainMenuView:

@IBAction func StartButton(sender: UIButton) {
    let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
    let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("GameViewController") as! GameViewController
    self.presentViewController(nextViewController, animated:true, completion:nil)
    restGame()
}

In the GameViewController, I use this code, but it doesn't dismiss the GameViewController.

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("GameOverView") as! GameOverView
self.presentViewController(nextViewController, animated:true, completion:nil)

This is My GameOverView Code :

class GameOverView: UIViewController{
    // save the presenting ViewController
    var presentingViewController :UIViewController! = self.presentViewController

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func ReplayButton(sender: UIButton) {
        restGame()
        didPressClose()
    }
    @IBAction func ReturnMainMenu(sender: UIButton) {
        Data.GameStarted = 1
        self.dismissViewControllerAnimated(false) {
            // go back to MainMenuView as the eyes of the user
            self.presentingViewController.dismissViewControllerAnimated(false, completion: nil);
        }
       /* let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("MainScene") as! MainScene
        self.presentViewController(nextViewController, animated:true, completion:nil)*/

    }
    func restGame(){
        Data.score = 0
        Data.GameHolder = 3
        Data.GameStarted = 1
        Data.PlayerLife = 3.0
        Data.BonusHolder = 30
        Data.BonusTimer = 0
    }
    func didPressClose()
    {
        self.self.dismissViewControllerAnimated(true, completion:nil)
    }
    override func shouldAutorotate() -> Bool {
        return false
    }

    deinit{
        print("GameOverView is being deInitialized.");

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }


}

Any suggestions?

Pilchard answered 11/8, 2015 at 22:17 Comment(0)
D
42

What you can do is let the GameOverView be presented, after all when you presenting it the GameViewController is below in the hierarchy, and then in your GameOverView run the following code to close both when you want to dismiss the GameOverView, like in the following way:

@IBAction func ReturnMainMenu(sender: UIButton) {
    // save the presenting ViewController
    var presentingViewController: UIViewController! = self.presentingViewController

    self.dismissViewControllerAnimated(false) {
          // go back to MainMenuView as the eyes of the user
          presentingViewController.dismissViewControllerAnimated(false, completion: nil)
    }
}

The above code need to be called when you want to dismiss the GameOverView.

I hope this help you.

Devereux answered 11/8, 2015 at 23:1 Comment(7)
it doesn't work it give an error "Getter for 'presentingViewController' with Objective-C selector 'presentingViewController' conflicts with getter for 'presentingViewController' from superclass 'UIViewController' with the same Objective-C selector" i updated my post so you can see my code for GameOverViewPilchard
First of all, var presentingViewController :UIViewController! = self.presentViewController outside a function doesn't work , you need to declare it and then inside your viewDidLoad instantiate it. Your problem is regarding that when you declare presentingViewController as a stored property the UIViewController make conflict with his own presentingViewController, solution: change the name. The above code is for be called inside a function to avoid this kind of conflicts.Devereux
Thanks for the help it return to MainMenu but the GameViewController isn't dismiss yet the memory wasn't releasedPilchard
What do you mean with "isn't dismiss yet the memory wasn't released"?Devereux
When i dismiss from GameViewController the memory decrease from 60MB to 40MB but if i dismiss from GameOverView the memory stay at 60MB and if i play again the game the memory increase from 60 to 100 MBPilchard
Then I recommend you to use Instruments and find where is the bug memory.Devereux
It work find now thanks but is it normal that every time i start the game this error is prompt "<CAMetalLayer: 0x14cdf9cb0>: calling -display has no effect." i don't use CAMetalLayer in my code how do i solve it thxPilchard
F
3

The below code will take you to the main VC, Here's a tried and tested piece of code.

self.view.window!.rootViewController?.dismiss(animated: false, completion: nil)
Fraley answered 30/1, 2018 at 8:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.