Reputation: 165
My Scenario, In my project I am maintaining three ViewController
(Main, VC1 and VC2)
. In main ViewController
I am maintaining UIButton
, This button click to VC1
presenting model view controller. Again, VC1
I am maintain UIButton
with action click to present model to VC2
. After VC2
presenting I need to dismiss VC1.
// 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)
}
Upvotes: 3
Views: 5124
Reputation: 51
You need to open vc2 from the mainVC - In order to do this you need a delegate method which will tell mainVC to close the current opened vc (i.e. vc1) and in the success block open vc2.
Code Snipet:-
dismiss(animated: false) { //Open vc2 present(vc2) }
Upvotes: 1
Reputation: 15778
Try this in VC2
's close button action
var vc = self.navigationController?.presentingViewController
while vc?.presentingViewController != nil {
vc = vc?.presentingViewController
}
vc?.dismiss(animated: true, completion: nil)
Upvotes: 2
Reputation: 24341
To solve the problem statement, what you can do is present VC2
using Main
instead of VC1
.
We can get the reference to Main
in VC1
using
self.presentingViewController
When VC2
is presented, dismiss VC1
in the completionHandler
of present(_:animated:completion:)
method
class Main: UIViewController {
@IBAction func onTapButton(_ sender: UIButton) {
let vc1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VC1")
self.present(vc1, animated: true, completion: nil)
}
}
class VC1: UIViewController {
@IBAction func onTapButton(_ sender: UIButton) {
let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VC2")
vc2.view.backgroundColor = .blue
self.dismiss(animated: false, completion: nil)
self.presentingViewController?.present(vc2, animated: true, completion: nil)
}
}
class VC2: UIViewController {
}
This approach is giving the expected output. Let me in case anything else is required.
Upvotes: 1
Reputation: 1957
There is a present(_:animated:completion:) method which takes a completion. Inside that you can dismiss
your VC1.
Your code will look something like this
@IBAction func ButtonTapped(_ sender: Any) {
present(VC2, animated: true) {
dismiss(animated: true, completion: nil)
}
}
Upvotes: 0
Reputation: 534
Hope this will work:
You need to have a UIViewController as a base, in this case MainViewController
is the base ViewController. You need to use a protocol to call the navigation between Controllers.
you can do using protocol:-
In to your FirstViewController setting Protocol :
protocol FirstViewControllerProtocol {
func dismissViewController()
}
class FirstViewController: UIViewController {
var delegate:FirstViewControllerProtocol!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func goBack(sender: AnyObject) {
self.dismissViewControllerAnimated(true) {
self.delegate!.dismissViewController()
}
}
Now in your MainViewController
class MainViewController: UIViewController, FirstViewControllerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func goToFirstViewController(sender: AnyObject) {
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(String(FirstViewController)) as! FirstViewController
viewController.delegate = self
self.presentViewController(viewController, animated: true, completion: nil)
}
//MARK: Protocol for dismiss
func dismissViewController() {
if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(String(SecondViewController)){
self.presentViewController(viewController, animated: true, completion: nil)
}
}
Upvotes: 1
Reputation: 44
In this case you need to call dismiss from the view controller over which your other view controllers are presented(Main in your case).
As you stated your situation in the question above Main presents VC1 and VC1 then presents VC2: then calling Main.dismiss(animated: true, completion: nil) will dismiss VC1 and VC2 simultaneously.
If you don't have a reference to the root controller(Main), you could chain a couple of presentingViewController properties to access it; Something like this in the topmost controller(VC2):
presentingViewController?.presentingViewController?.dismiss(animated: true)
I hope this helps.
Upvotes: 0