The back button does not appear in the navigation bar until you turn

I have three view controllers: ABC , controlled by the navigation controller. A is a time controller. It is requesting a server for something. If the server says that everything is in order, then A pushes B onto the stack. B must hide the back button because I don't want users to manually go back to A

 // B view controller - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.hidesBackButton = YES; self.title = @"B"; } 

B then pushes C onto the stack when the user deletes a table cell.

 // B view controller - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { C *c = [[C alloc] initWithStyle:UITableViewStyleGrouped ]; [self.navigationController pushViewController:c animated:YES ]; [c release]; } 

.

 // C view controller - (void) viewDidLoad { [super viewDidLoad]; self.navigationItem.hidesBackButton = NO; self.title = @"C"; } 

If all goes well, the stream should look like this:

 ------------- ------------- ------------- |_____A_____| |_____B ____| | <B|__ C___| | | => | | => | | | loading...| | cells | | detail | | | | | | | ------------- ------------- ----------- 

For some reason, C doesn't show the back button to go back to B until I rotate the device. After turning, the back button appears in all orientations. It seems that the problem is that B hiding the back button and C trying to show it again, because if I don't let B hide it, I don't have this problem. So, how do I get C to show the back button without forcing the user to rotate the device like a monkey?

Update

  • Broken on two different iPhone Verizon 4 on iOS 4.2.10
  • Works great on AT&T iPhone 3GS on iOS 5.0.
  • Works great on AT&T iPhone 4 on iOS 4.3.
+7
source share
6 answers

After some searching, I found this solution for iPhone 4.2 (since you posted it in later versions) on some old forum.

 -(void)viewDidLoad { [super viewDidLoad]; self.navigationItem.hidesBackButton = YES; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.navigationItem.hidesBackButton = NO; } 

Perhaps this will help you. (Check this: The back button does not appear in the navigationController )

+4
source

I think you need to put your code as shown in C

 -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.navigationItem.hidesBackButton = NO; } 
+1
source

I had this problem and solved it by specifying the navigation item B in the title

 // B view controller - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.hidesBackButton = YES; self.navigationItem.title = @"What you want C back button to say"; self.title = @"B"; } 

If you do not want the title to appear in B, you can set the B navigationItem titleView to an empty view. About the titleView property:

If this property value is nil, the title bar of the navigation items is displayed in the center of the navigation bar when the receiver is the top item. If you set this property to a custom title, it is displayed instead of the name. This property is ignored if leftBarButtonItem is non-zero.

0
source

Try putting self.navigationItem.hidesBackButton = NO; to the init method or anywhere before pushViewController is called.

ViewDidLoad is called when you request the controller for the first time, which means it is probably called from [self.navigationController pushViewController:c animated:YES] . But note that the navigation bar is not part of your view, it is created and processed by the UINavigationController , so in principle it can exist and be drawn even before calling viewDidLoad and viewDidAppear. If you update the navigation bar there, it will not actually be repainted.

Edit 1: Repeat after reading the documentation for [UIViewController navigationItem]

You should not associate the creation of panel elements in a navigation element with the creation of the view of your view controllers. The view controller navigation element can be obtained regardless of the type of view controllers. For example, when two view controllers are pressed on the navigation stack, the top view controller becomes visible, but another visibility manager navigation element can be retrieved to present its return button. To customize a navigation element, you can override this property and add code to load elements of the bar panel or load elements into the initialization code of your controller.

Edit 2: Repeat after reading the comment that my solution is not working. Work Code (iOS 5, ARC):

 // // TestAppDelegate.m // NavigationTest // // Created by Sulthan on 10/25/11. // Copyright (c) 2011 StackOverflow. All rights reserved. // #import "TestAppDelegate.h" @interface TestAppDelegate () @property (nonatomic, strong, readwrite) UINavigationController* navigationScreen; @property (nonatomic, strong, readwrite) UIViewController* screen1; @property (nonatomic, strong, readwrite) UIViewController* screen2; @property (nonatomic, strong, readwrite) UIViewController* screen3; @end @implementation TestAppDelegate @synthesize window = window_; @synthesize navigationScreen = navigationScreen_; @synthesize screen1 = screen1_; @synthesize screen2 = screen2_; @synthesize screen3 = screen3_; - (UIViewController*)createTestScreenWithLabel:(NSString*)label { CGRect bounds = [[UIScreen mainScreen] bounds]; UIViewController* screen = [[UIViewController alloc] init]; screen.view = [[UILabel alloc] initWithFrame:bounds]; screen.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); ((UILabel*) screen.view).textAlignment = UITextAlignmentCenter; ((UILabel*) screen.view).text = label; return screen; } - (void)pushThirdScreen { if (!self.screen3) { self.screen3 = [self createTestScreenWithLabel:@"Screen 3"]; self.screen3.navigationItem.hidesBackButton = NO; } [self.navigationScreen pushViewController:self.screen3 animated:YES]; } - (void)pushSecondScreen { self.screen2 = [self createTestScreenWithLabel:@"Screen 2"]; self.screen2.navigationItem.hidesBackButton = YES; UIBarButtonItem* button = [[UIBarButtonItem alloc] initWithTitle:@"Go" style:UIBarButtonItemStyleBordered target:self action:@selector(pushThirdScreen)]; self.screen2.navigationItem.rightBarButtonItem = button; [self.navigationScreen pushViewController:self.screen2 animated:YES]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ CGRect bounds = [[UIScreen mainScreen] bounds]; self.screen1 = [self createTestScreenWithLabel:@"Screen 1"]; self.navigationScreen = [[UINavigationController alloc] initWithRootViewController:self.screen1]; self.window = [[UIWindow alloc] initWithFrame:bounds]; self.window.backgroundColor = [UIColor whiteColor]; [self.window addSubview:self.navigationScreen.view]; [self.window makeKeyAndVisible]; [self performSelector:@selector(pushSecondScreen) withObject:nil afterDelay:3.0]; return YES; } @end 

Edit 3: Repeat, noticing that you are talking mainly about iOS 4.2. Currently, I cannot test it on any iOS 4.2, but I know of a possible workaround. You can always hide the navigation bar in your UINavigationController and simply place a separate navigation bar on each screen. You will have absolute control over them, and you can even edit them in Interface Builder.

0
source

Try adding this to your C class:

 -(id) init { [super init]; self.navigationItem.hidesBackButton = NO; } 
0
source

Not sure if this will work for your back button situation, but I know that when I use the custom back button, I need to set the custom back button on the alloc'd element before I click it (not like the message above). Hope it works for your situation too - it's worth a try.

In other words, try:

 // B view controller - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { C *c = [[C alloc] initWithStyle:UITableViewStyleGrouped]; // *** set on c navigationItem (not self) before you push [[c navigationItem] setHidesBackButton: NO]; [self.navigationController pushViewController:c animated:YES ]; [c release]; } 
0
source

All Articles