Mohammad Hossein
Mohammad Hossein

Reputation: 107

Show second modal view controller after first was closed

I have two view controller that opens modally. When the first VC closed then the second should be opened. But when I close the first one, the second one is not displayed at all. what is the problem?

My code is:

self.dismiss(animated: true) {
        let flowVC = LanguageFlowViewController()
        self.present(flowVC, animated: true)
    }

Upvotes: 0

Views: 524

Answers (3)

vivek
vivek

Reputation: 268

If you want to open modally ThirdViewController after Dismiss SecondViewController then you have to create protocol for it.

Like we have three UIViewController(FirstViewController,SecondViewController and ThirdViewController)

Step 1: We need to create a protocol in SecondViewController as given below code.

protocol DismissedViewProtocal {
    func dismissView()
}

class SecondViewController: UIViewController {
    
    var delegate: DismissedViewProtocal?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
    }
    
    @IBAction func dismissSecondViewAction(_sender : AnyObject) {
        dismiss(animated: true) {
            self.delegate?.dismissView()
    }        
}   

Step 2: You need to add protocol in FirstViewController as given below

class FirstViewController: UIViewController, DismissedViewProtocal {
    
    override func viewDidLoad() {
            super.viewDidLoad()
    }

    @IBAction func anAction(_sender : AnyObject){
            let flowVC = self.storyboard?.instantiateViewController(withIdentifier:"SecondViewController") as? SecondViewController
            secondVC?.delegate = self
            self.present(secondVC!, animated: true) {
            
            }
        }

    func dismissView() {
        let thirdVC = self.storyboard?.instantiateViewController(withIdentifier:"ThirdViewController")
            self.present(thirdVC!, animated: true) {
        }
    }
}

Upvotes: 1

Sagar Chauhan
Sagar Chauhan

Reputation: 5823

You need reference of view controller from where you to present first view controller.

For example, you have view controller name as X, from there your first view controller A present. So you need reference of X to present B, because A will not be available in memory.

So when you try to present second view controller using self, it will do nothing.

So, for solution assign reference of X view controller to A. In class A, declare:

var refX: X?

While present A from X, set self to refX. Like:

var aVC = A() // This is temp, you need to instantiate your view controller here.
aVC.refX = self
self.present(aVC, animated: true, completion: nil)

Now, inside view controller A, when dismiss:

var bVC = B() // This is temp, you need to instantiate your view controller here.
self.dismiss(animated: true) {
    if self.refX != nil {
        self.refX?.present(bVC, animated: true, completion: nil)
    }
}

I hope this will help you.

Upvotes: 3

Justin Ganzer
Justin Ganzer

Reputation: 692

Your are dismissing the current view controller by calling self.dismiss(). Therefore it is impossible for it to present anything anymore, since it is removed from the view hierarchy. As others have mentioned, try using the self.presentingViewController or self.navigationController (if it is on a navigationController) to present your new view.

However, if you need maximum flexibility create a delegate protocol. Create a protocol with a function presentForChild(viewController: UIViewController). Before your previous view presents the view from which the code in your question belongs to, give it a reference of the protocol.

Example:

protocol ChildPresentDelegate: class {
    func presentForChild(vc: UIViewController)
}

class FirstController: UIViewController, ChildPresentDelegate {

    func presentForChild(vc: UIViewController) {
        present(vc, animated: true, completion: nil)
    }

    /**
     other code
     */

    func showControllerAsWasShownInTheQuestion() {
        let controller = SecondController()
        controller.delegate = self
        present(controller, animated: true, completion: nil)
    }
}

class SecondController: UIViewController {
    weak var delegate: ChildPresentDelegate?

    func dismissMySelf() {
        self.dismiss(animated: true) {
            delegate?.presentForChild(vc: LanguageFlowViewController())
        }
    }
}

Upvotes: 1

Related Questions