Joe
Joe

Reputation: 3961

Using viewDidAppear to present a View Controller, re-opening it when it's closed

In my App, I've created a new storyboard that serves as a very basic tutorial for how to use certain features. (Instructions.storyboard). This storyboard has it's own class - InstructionsVC.swift

I want to present InstructionsVC when MainVC loads within viewDidAppear.

It works great. Fires up on App load just like it's supposed to. The problem occurs when I press the [Close] button on the Instructions interface. It closes the VC, fades to the main screen, and then immediately fires the Instructions VC back up.

How can I prevent the Instructions VC from loading back up once it's closed?

func openInstructions() {
    let storyboard = UIStoryboard(name: "Instructions", bundle: nil)
    let instructionsView = storyboard.instantiateViewController(withIdentifier: "instructionsStoryboardID")
    instructionsView.modalPresentationStyle = .fullScreen
    instructionsView.modalTransitionStyle = .crossDissolve
    self.present(instructionsView, animated: true, completion:nil)
}

override func viewDidAppear(_ animated: Bool) {
    openInstructions()
}

And within my instructions class, I have the following action on the close button:

@IBAction func closeButtonPressed(_ sender: UIButton) {
    let presentingViewController: UIViewController! = self.presentingViewController
    presentingViewController.dismiss(animated: true, completion: nil)
}

Note - I'd rather not use UserDefaults to resolve this, because I'm going to be incorporating something similar in other parts of the App and don't want to resort to UserDefaults to achieve the desirable behavior.

Thanks in advance buddies!

Upvotes: 0

Views: 1920

Answers (1)

Duncan C
Duncan C

Reputation: 131426

viewWillAppear and viewDidAppear are called every time a view controller's content view becomes visible. That includes the first time it's rendered and when it's shown again after being covered by a modal or by another view controller being pushed on top of it in a navigation stack.

viewDidLoad is only called once when a view controller's content view has been loaded, but before it is displayed. Thus when viewDidLoad is called it may be too soon to invoke your second view controller.

You might want to add an instance variable hasBeenDisplayed to your view controller. In viewDidAppear, check hasBeenDisplayed. If it's false, display your second view controller and set hasBeenDisplayed to true.

Upvotes: 3

Related Questions