1

I have an UINavigationController in my iPhone app controlling views in a drill-down fashion. In the second last view I'd like to return to the root view by pressing the default back button. I know that the method popToRootViewControllerAnimated: does just that. But where do I place it?

ZviBar
  • 9,758
  • 6
  • 25
  • 30

4 Answers4

3

One option is to use leftBarButtonItem rather than backBarButtonItem on self.navigationItem. i.e.

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(popToRootViewController:)];

Which would then call the selector popToRootViewController in your view controller, which could be implemented like so:

-(void)popToRootViewController:(id)sender {
    [self.navigationController popToRootViewControllerAnimated:YES];
}

The issue that I see is that you won't have the native back button appearance.

Another option is to change the target and selector property on the backBarButtonItem.

[self.navigationItem.backBarButtonItem setTarget:yourTarget]
[self.navigationItem.backBarButtonItem setSelector:@selector(popToRootViewController:)]

Be aware that the backBarButtonItem should be set on the view controller in the stack that comes before the view controller where you would like the button to be visible:

self.navigationController.viewControllers
| ...
|
|-- SecondViewController <-- Set the backBarButtonItem here to be visible on LastViewController
|-- LastViewController

HighFlyingFantasy
  • 3,789
  • 2
  • 26
  • 38
2

As far as I know, you can not pop to Root ViewController through the default back button because this default button is only for popping into the previous view Controller. So, if you want to pop back to the root ViewController, you can make make a custom bar button on the navigation bar and you can use popToRootViewControllerAnimated: in the selector method of this custom bar button. If you want to use only one back button for popping to root ViewController, you can simply hide your default back button by using this:

self.navigationItem.hidesBackButton = YES;

And then, you can add your custom back button on your navigation bar through which you can pop to root ViewController.

Please let me know if it works. Thanks :)

  • Yes I tried that already and it works. I am however unable to make the new button look exactly as the default back button. The original one has this '<' sign and am not sure how to get it. – ZviBar Jan 25 '14 at 16:33
  • are you using storyboard or you are creating button programatically? – Sudershan shastri Jan 25 '14 at 16:40
  • Ok. Are you trying to use only one back button on the left side and not trying to create another back button on the right to pop to RootViewController? – Sudershan shastri Jan 25 '14 at 16:56
  • Yep. But the thing is that it is not clear how to make it look exactly like the back button both in ios 6 and 7. – ZviBar Jan 25 '14 at 17:02
  • I am able to create a bar button which looks exactly like the default button simply by using storyboard and giving it a title i.e"Back". I don't know whats going wrong in your case. Please go through the edited answer once. – Sudershan shastri Jan 25 '14 at 17:10
  • Nope it didn't. Thanks for trying. – ZviBar Jan 26 '14 at 18:43
2

You can use viewWillDisappear

-(void) viewWillDisappear {
    NSArray *viewControllers = self.navigationController.viewControllers;
    if ([viewControllers indexOfObject:self] == NSNotFound) {
      // View is disappearing because it was popped from the stack
      [self.navigationController popToRootViewControllerAnimated:YES];
  }
}

Got some code from here: viewWillDisappear: Determine whether view controller is being popped or is showing a sub-view controller

This code will pop to the root view controller when the view is being popped (which happens when the back button is pressed).

Community
  • 1
  • 1
John Farkerson
  • 2,543
  • 2
  • 23
  • 33
0

You should subclass your UINavigationController and overwrite the method popViewControllerAnimated(animated: Bool).

override func popViewControllerAnimated(animated: Bool) -> UIViewController? {
    guard let last = self.viewControllers.last else {
        return nil
    }
    if last.isKindOfClass(MySecondLastViewController.self) {
        return super.popToRootViewControllerAnimated(animated)![0]
    } else {
        if self.viewControllers.count >= 2 {
            return super.popViewControllerAnimated(animated)
        } else {
            return nil
        }
    }
}
Chris Wood
  • 306
  • 3
  • 13