6

I need to go to the first view in my app. I have a few views pushed onto the stack then a modal navigation controller and more views pushed onto that.

The problem I'm having is that using [[self navigationController] popToRootViewControllerAnimated:YES]; only goes back to the first view in the modal stack.

And I can't get [[self navigationController] popToViewController:.. to work because the true first view controller isn't accesible with [[self navigationController] viewControllers].

Any ideas on how to accomplish this? Thanks.

ScottF
  • 565
  • 6
  • 21
  • Which navigationController are you calling? It will pop to the root of the navigation controller called I imagine. – Alan Moore Apr 13 '12 at 21:02
  • Make the first view controller as the rootViewcontroller of your navigationController – Ankit Srivastava Apr 13 '12 at 21:09
  • Close the modal view controller, then pop to root. – Till Apr 13 '12 at 21:14
  • How can I get a reference to the original navigation controller, not the new one that was pushed with the modal transition? – ScottF Apr 13 '12 at 21:27
  • See [this](http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html) you have a property presentingViewController – Mat Apr 13 '12 at 21:38

4 Answers4

6

Do this:

[[self navigationController] dismissModalViewControllerAnimated:YES];

That will get you back to the VC that modally presented the navigation controller. Getting farther back after that depend on how you pushed those "few views" before the navigation controller.

Edit - explanation to get to the deepest root...

It sounds like those "few views" are on another, underlying navigation controller's stack. This can be a little tricky, because the clean way to get farther back in that stack is to have that underlying navigation controller pop to it's own root. But how can it know that the modal VC on top of it is done?

Let's call the view controller that did the modal presentation of second navigation controller VC_a. It's a modally presented navigation controller whose topmost VC is VC_b. How can VC_a know to pop to it's navigation root when VC_b modally dismisses itself?

The good answer (usually) is that VC_b decided to dismiss itself for a reason - some condition in your app/model changed to make it decide to be done.

We want VC_a to detect this condition, too. When VC_b gets dismissed, and VC_a gets a viewWillAppear message because it's about to be uncovered:

// VC_a.m

- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];
    if (/* some app condition that's true when VC_b is done */) {
        // I must be appearing because VC_b is done, and I'm being uncovered
        // That means I'm done, too.  So pop...
        [self.navigationController popToRootViewControllerAnimated:NO];
    } else {
        // I must be appearing for the normal reason, because I was just pushed onto the stack
    }
}
danh
  • 62,181
  • 10
  • 95
  • 136
  • My problem is that prior to dismissing the modal view controller, I have no reference to the view that will be at the top of the stack to tell it to popToRoot. All the other views before the single modal view were pushed with a push transition using performSegueWithIdentifier, none of them are modal. – ScottF Apr 13 '12 at 21:25
  • But the one that did the modal presentation of the second navigation controller knows who it is. That one will know that the nav controller is dismissed when it gets a (second) viewWillAppear. That one can pop itself. Please see my edit. – danh Apr 13 '12 at 21:44
  • In other words, the dismissing one doesn't know who to pop, and shouldn't. The presenting one does. – danh Apr 13 '12 at 21:45
  • on the last view, i just set a flag in the app delegate and in the viewwillappear of the view that would show up after dismissing the modal view, i checked that flag to see if i needed to poptoroot. – ScottF Apr 13 '12 at 21:50
  • Glad it worked, though I hope you can find a better solution than the flag...Maybe something related to what the modal vc was doing - e.g. say it's job was to get a valid password from the user, if the user object is accessible to both presenter and presented, then the presenter's "flag" is user.password != nil. See what I mean? – danh Apr 13 '12 at 21:55
0

You need to do it by using the delegation pattern. Specifically, by creating a protocol that implements the delegate's respondsToSelector method.

See this post for complete details. It should be almost exactly what you are looking for. I had to do something similar, except I only needed to pop one view off the navigation stack instead of using popToRootViewControllerAnimated:.

Community
  • 1
  • 1
elusive
  • 460
  • 5
  • 24
  • this looks like it would work as well, I could implement it quicker with the code from the edit on the above answer. thanks though – ScottF Apr 13 '12 at 21:48
0

In AppDelegate.m class create method with bellow flow...

-(void)MethodName{//your method name
    YourViewController *objViewController = [[[YourViewController alloc] initWithNibName:@"YourViewController" bundle:nil] autorelease]; ///define your viewcontroller name like "FirstViewController" 
    UINavigationController *yourNavigationController = [[[UINavigationController alloc] initWithRootViewController:objViewController] autorelease];

    self.window.rootViewController = yourNavigationController;
}

When you want redirect on firstview just call this method from appdelegate object....

Pang
  • 9,564
  • 146
  • 81
  • 122
Paras Joshi
  • 20,427
  • 11
  • 57
  • 70
0

For iOS6...

[self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
MLBDG
  • 1,357
  • 17
  • 23