dismiss current view controller AFTER presenting new view controller - swift
Asked Answered
G

5

17

I'm trying to dismiss a VC and present a new VC. but I don't want old VC to exist anymore. I use the code below to dismiss current VC and present new one. but this way, there's a time interval between dismiss and present. I don't want the user to notice this. so, I want to present new VC first and then dismiss previous one. Is there any way to do this?

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationController = self.storyboard?.instantiateViewController(withIdentifier: "login") as! Login
let presentingVC = self.presentingViewController
self.dismiss(animated: false, completion: { () -> Void   in
    presentingVC!.present(destinationController, animated: true, completion: nil)
})
Gustaf answered 20/2, 2017 at 8:9 Comment(6)
Why don't you just call it sequentially, first present, then dismiss (and not in the completion handler of the present)? So: presentingVC!.present(destinationController, animated: true, completion: nil); self.dismiss(animated: false, completion:nil)Jenisejenkel
Friend why do you are dismissing that currentVc from stack?Jargonize
directly you can dismiss when you want by making animation false.Jargonize
@AndreasOetjen if I do it that way, it first presents and the dismiss new VC, not the old oneGustaf
@Mukesh because I dont wanna show it again when users goes back again. and how making animation false helps me?Gustaf
@AndreasOetjen doing present and dismiss together will present the new view and dismiss the same. Try it. We must handle it in completion handler.Gerena
R
12

I think the best way will be to dismiss the current VC when you actually go back. That means, present your destinationController using the current VC and then when you go back, dismiss both VC's

Randalrandall answered 20/2, 2017 at 8:41 Comment(1)
I think this would be a better idea, thanks for help.Gustaf
V
12

Disclaimer

So unless you absolutely need to modally present your new VC, then I recommend just performing a segue between the two VCs. It seems that you are only presenting it modally because you want to manually dismiss it later from the original VC. Not only is using a segue this easier in my opinion, but it will also allow you to use the method I've outlined below.

Solution

This likely isn't the most elegant method, but you could pass the instance of the old VC through prepareForSegue to the next VC, and then dismiss it in the new VC's viewDidLoad.

For example, in your new VC you could have something like this:

class NewVC: UIViewController {

    ...
    var prevVC: PrevVC!

    override func viewDidLoad() {
        super.viewDidLoad()

        prevVC.dismiss(animated: false, completion: nil)
    }

}

So when your newVC loads, it dismisses the previous VC. All you would need to do in your prevVC class is pass on the instance in prepareForSegue like so.

class PrevVC: UIViewController {
    ...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destinationVC = segue.destination as? NewVC {

            destinationVC.prevVC = self

        }
    }

}

Then of course you would just have to present the newVC when you want and then everything else would be taken care of.

Vitavitaceous answered 20/2, 2017 at 8:48 Comment(2)
it looks like he is presenting the VC's in a modal way, so wouldn't dismiss-call on the presenting VC dismiss the presented VC as well?Randalrandall
@Randalrandall Ah I see the dilemma here. Didn't see that. Luckily, it seems that he is only presenting modally so that he could dismiss it manually later. Thus, if he just performed a segue then there shouldn't be an issue. I'll edit my post to include this information.Vitavitaceous
D
2

If you want to present VC B from VC A and want to dismiss VC A while Presenting, you can use this code:

You write this code in your VC A from which Button you want to present the VC B.

let parentVC = presentingViewController
dismiss(animated: true) {
    let vc = self.storyboard!.instantiateViewController(withIdentifier...)
    parentVC.present(vc, animated: true)`enter code here`
}
Donyadoodad answered 5/2, 2020 at 4:51 Comment(1)
it might be the wrong answer in specfic cases since it goes back to the PresentingViewController of the parentVCAdi
O
0

The way I do it is to use both

view.dismiss(animated: true, completion: nil)

and

presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)

depend on how many view controllers before. Because they are all optional, Xcode will not complain if you don't have them when you are trying to dismiss. If that is the case, the single dismiss() function will work just fine.

I guess it is because I didn't have a good design in the first place, it works but I don't think you will run into this if you have a good structure in the first place.

Orchestra answered 25/2, 2020 at 2:26 Comment(0)
B
0

So I just tried this in Xcode13. VC_A does a segue to VC_B. I tried to dismiss VC_A after the segue as well as passing the VC_A to VC_B and dismissing VC_A in the viewDidLoad of VC_B. When I dismiss VC_B it goes back to VC_A (also did a print of the deinit and it never gets called).

Bathsheeb answered 20/8, 2021 at 14:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.