11

So I created a UINavigationController manually, set it as my UIWindow's rootViewController, and I would like to use a back button to exit the UINavigationController and load another viewController in its place. However, the backItem property of the UINavigationBar is readonly, so I don't know how to set it properly (it is readonly and defaults to nil in the root navigation view). How can I achieve this (or similar effect, I want to be able to effectively "exit" this UINavigationController by pressing the back button on the root view).

Alternatively, is this bad form? How should I escape the root view of a UINavigationController?

EDIT:

Attempted Legolas' solution with the following code: (some names have been changed)

UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:plvc]; // plvc being the first viewcontroller
MyAppDelegate* appDelegate = [Utility getAppDelegate];
appDelegate.window.rootViewController = navController;

UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:@"Start" style:UIBarButtonItemStyleBordered target:self action:@selector(initializeStuff)];
navController.navigationItem.leftBarButtonItem = backButton;
[navController.navigationItem setHidesBackButton:YES animated:YES];
[navController.view setNeedsDisplay];

But the button does not display. What am I doing wrong? The other back buttons display properly, but this one still does not.

EmptyStack
  • 51,274
  • 23
  • 147
  • 178
adam_0
  • 6,920
  • 6
  • 40
  • 52
  • 1
    LOL. FYI . I copied your code EXACT and it works! Go to the ViewDidLoad method of your particular view. put those three things I have pasted. – Legolas Jun 06 '11 at 03:34

3 Answers3

16

You can do this in a different approach.

Go to the method:

- (void)viewDidLoad

Hide the back button with

[self.navigationItem setHidesBackButton:YES animated:YES];

Create a new UIButton or a UIBarButtonItem, and place it in place of the back button.

You can then use an action when you click the button

- (IBAction) clickBackButton : (id) sender; //and push view controller to your required view.

Updating my answer: Use this in the viewDidLoad method //works like a charm //

[self.navigationItem setHidesBackButton:YES animated:YES];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:@"Start" style:UIBarButtonItemStyleBordered target:self action:@selector(initializeStuff)];

self.navigationItem.leftBarButtonItem = backButton;
Legolas
  • 12,145
  • 12
  • 79
  • 132
  • Okay, but won't hiding the back button hide it as well for any subviews? I want to use it there, and I'd only like to exit from the root view – adam_0 Jun 06 '11 at 02:46
  • I do not know how you have created new views as you have not posted any code on how the app works. But I dont think it would hide it for all subviews. Use this idea and create this button only to the view you are looking to exit. It wouldn't harm to try [self.navigationItem setHidesBackButton:YES animated:YES]; in one view and experiment it :) – Legolas Jun 06 '11 at 02:51
  • Just noticed that my code (above) isn't in `viewDidLoad`, but in a method called by an external ViewController's method, an `IBAction` called by a button press (in a .xib). Is this still OK? I don't subclass the `UINavigationController`, the Apple docs say that's a bad idea. – adam_0 Jun 06 '11 at 03:32
  • Okay, so I put those lines in the `plvc` class implementation's `viewDidLoad`... still nothing. – adam_0 Jun 06 '11 at 03:40
  • No. Why would you initialize this in an IBAction. This has to be done in the viewDidLoad button. You need this button as soon as the view loads right ? – Legolas Jun 06 '11 at 03:40
  • Lol. come to chat. I think I can help you there. – Legolas Jun 06 '11 at 03:40
  • I got it figured out, I was using the wrong class in place of 'self' (because I was working in a different class, so I mistakenly thought self should be something else) >_ – adam_0 Jun 06 '11 at 05:00
3

There are a few approaches I can think of.

  1. Use your own "back button" icon of your own design, or a system default. Use leftBarButtonItem.
  2. Make an image of the default icon. Again, use leftBarButtonItem.
  3. Make a fake root view that you push into the UINavigationController stack. The sole purpose of this root view will be to launch the secondary view, or die when the user comes back to it. This way, you will never see UINavigationController without a back button. I've tested this (but not profiled it); performance impact seems negligible.

Also, check out <https://discussions.apple.com/message/8298537#8298537> from 2008. Same question.

The problem is, how does the user get out of a UINavigationController and back to the app? The root navigation bar doesn't have a back button or any sort of hook to exit.

To which someone replied:

To do what you want to do, the trick is to put the "super-root" controller inside the navigation controller, but have it set the nav controller's navigationBarHidden property to YES in viewWillAppear and NO in viewWillDisappear. (For bonus points, animate it when appropriate.)

kanzure
  • 1,331
  • 11
  • 15
0

try dis:-

UIBarButtonItem *leftBarButton  = [[UIBarButtonItem alloc] initWithTitle:@"back" style:UIBarButtonItemStylePlain target:self action:@selector(initializeStuff)];
[self.navigationItem setleftBarButtonItem:leftBarButton];
[leftBarButton release];
EmptyStack
  • 51,274
  • 23
  • 147
  • 178
vijay adhikari
  • 2,455
  • 1
  • 16
  • 22