user2228755
user2228755

Reputation: 407

Trying to understand dismissing ViewControllers

I was trying to dismiss a view controller and there are several methods to call that all seem to similar. #1 worked but the others didn't. When should I use one of these but not the other?

1. [self dismissViewControllerAnimated:YES completion:nil]; (this one worked).
2. [self.parentViewController.navigationController popViewControllerAnimated:YES];
3. [self.navigationController popViewControllerAnimated:YES];
4. [self performSegueWithIdentifier:@"showPreviousController" sender:self];
5. [self.navigationController popToRootViewControllerAnimated:YES];

Upvotes: 0

Views: 184

Answers (2)

juniperi
juniperi

Reputation: 3763

[self dismissViewControllerAnimated:YES completion:nil];

This works fine if you don't have navigation controller and you want to jump back to previous view controller.

Next button jumps to view controller B and when dismiss button is pressed it call's dismissViewControllerAnimated: method and jumps back to first view controller.


[self.parentViewController.navigationController popViewControllerAnimated:YES];

Quote from Apple's documentation about parentViewController:

If the recipient is a child of a container view controller, this property holds the view controller it is contained in. If the recipient has no parent, the value in this property is nil.


[self.navigationController popViewControllerAnimated:YES];

This jumps back to previous view controller. You need navigation controller set up to use this method. Otherwise nothing happens.

If you press Dismiss button in view controller B and that button calls popViewControllerAnimated: method, it will jump back to view controller A.


[self performSegueWithIdentifier:@"showPreviousController" sender:self];

This performs seque with identifier as it says. In storyboard you can set identifier for seques.

When you have seque selected, you can set identifier in Attributes inspector:


[self.navigationController popToRootViewControllerAnimated:YES];

This jumps back to first view controller. Called root controller. So if you have 5 view controllers (A -> B -> C -> D and E) and you call popToRootViewControllerAnimated: at E, it will jump back to A-controller.

Upvotes: 1

Gabriele Petronella
Gabriele Petronella

Reputation: 108101

Those methods all do different things, I suggest you read the View Controller Programming Guide, since you are mixing up several concepts.

However here's a summary of what they do:

[self dismissViewControllerAnimated:YES completion:nil]; (this one worked).

Dismiss the view controller presented by this controller (self).


[self.parentViewController.navigationController popViewControllerAnimated:YES];

Pop the top view controller in the parent's navigation controller. This is weird and probably wrong. parentViewController is the view controller the current one is embedded in. You are accessing its navigation controller and making it pop the view controller on top of the stack. It will silently fail in case:

  • parentViewController is nil
  • navigationController is nil

[self.navigationController popViewControllerAnimated:YES];

Pop che view controller on top of the current navigation stack. Makes sense in case the current controller has been pushed by the navigation controller (and not presented modally).


[self performSegueWithIdentifier:@"showPreviousController" sender:self];

Well, this is performing the showPrviousController segue, whatever it does...


[self.navigationController popToRootViewControllerAnimated:YES];

This make the current navigation controller to pop all the view controllers, except the root one, which will remain on top.

Upvotes: 0

Related Questions