Can't get default UINavigationController back button to work - ios

First, I've read almost all of the questions and answers on the web and SO about navigation bar/back button/title/navigation item etc. I have a navigation controller and view controllers. Nothing fancy. Whatever I do, I can't display a back button when I push a new view controller. Neither via storyboard push segues nor programmatically pushing. My view controller and navigation bar displays correctly, when I tap where where the back button should be, it does work, it pops the view controller, however, it's not displayed.
Before you say, I'll list what I've done:
I've got the navigation controller's Shows Navigation Bar set to yes.
I've set a title to my root view controller inside the navigation controller on storyboard.
I've set a back button title to my root view controller inside the navigation controller on storyboard.
I don't have any custom code involving navigation bar/navigation item/left bar button/right bar button/hides back button/back button item.
I've set a title for my navigation controller.
Whatever I do, my back button doesn't get displayed. When I debug, it's set to nil. I've tried instantiating one but it didn't help either. What am I missing?

Firstly check that the controller you are pushing from and to has a navigation item in the viewer you can set title, back button and prompt for. I have found that depending on how storyboard has created the controller it may or may not have one you can see in the view tree. Setting the back button does not seem to work unless you can actually see one in both controllers in storyboard.
Secondly, and something I only realized recently, is that you set the title for the back button in the controller you are pushing "from" and not in the controller that will be showing when the back button is showing.
e.g. If you have controller A and controller B and you are pushing to B from A: you have to set the label for the back button in the navigationItem of controller A, not in the navigationItem of controller B. You may already know this, but its confusing.

define a property in .h
#property (strong, nonatomic) UIBarButtonItem *backButton;
in viewDidLoad in .m
self.backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"backButton.png"] style:UIBarButtonItemStylePlain target:self action:#selector(backButtonPressed)];
self.navigationItem.backBarButtonItem = self.backButton;
and add the method
-(void) backButtonPressed {
[self.navigationController popViewControllerAnimated:YES];
}
oh misread... you don t want a custom button, just the normal one? maybe there is a UIBarButtonSystemItem for back ?? take this instead of a custom image...
checked tintcolor? maybe it s set to clearcolor ??

It was something much simpler. Actually, everything was acting correctly. After some investigation ([[UIWindow keyWindow] recursiveDescription]) I've realized that it was just me who was faulty to set the storyboard's global tint color to the same color with navigation bar. I've explicitly set the tint to white and now the text is seen.

Related

Navigate from a navigation bar view controller to a tab bar view controller

What is wrong with this approach? There is no coding behind it. But, I cannot see the item nor the title of the last scene on the right (as their titles are set to "cannot see").
Even if I add a back button, and set it's title to something, it keeps showing the default back button.
The storyboard
You are pushing UITabBarViewController instance in to UINavigationViewController stack. In such case navigation bar is managed by UINavigationController that is way you don't see "Cannot see" UIBarButtonItem in the nav bar.
UITabBarViewController works best if it is the rootViewController of the application. Take a look at this unswear to see how UITabBarViewController should be used.

Unable to configure UINavigationBar for view embedded in Tab Bar Controller

I a writing an app (iOS8) that ultimately needs to load a UITabBarController via a segue from a UITableView. For the most part this setup can be done via Storyboards and works as expected, however I would also like to add a UIButtonBarItem to the destination view which is where the problems start.
A setup that works (without a UITabBarController) can be configured as follows
The button uses a "Show" segue to display the final view controller
The second UIBarButtonItems are added by copying over the Navigation Item from the first view controller (How to add buttons to navigation controller visible after segueing?)
If I run this in the Simulator, everything works as expected and I see both the back button and the desired "Add" UIBarButtonItem:
If I then embed the final view controller in a UITabBarController, the UIBarButtonItem I added disappears and so far any changes I have made to the storyboard setup (adding a UINavigationController in between the UITabBarContoller and the last view for example) or attempts to add the UIBarButtonItem programatically don't make a difference:
Is there anyway to get the final setup working with both a UITabBarController and UIBarButtonItems?
I have the same setup in one of my apps and it works fine. Not sure why you are having issues, but I did add a few lines of code in my custom Tab Controller that may help you. I think the issue is that the nav bar from the original navigation controller is still being shown, so subclass UITabBarController and put these lines in viewWillAppear:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationItem setHidesBackButton:YES];
[self.navigationController setNavigationBarHidden:YES];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
In my app, the views before the tab bar controller were login/register views, so there was no reason to navigate back to them after entering the tab controller "stack," but I'm sure it won't be difficult to add a back button that accomplishes this. I believe you only need the [self.navigationController setNavigationBarHidden:YES]; line, which only hides the nav bar instead of hiding the back button or disallowing the pop gesture.
I know this is late but I just want to add swift 3 code.
The reason being that the NavigationBarA of the tabBarController is hiding your NavigationBarB that sits in between your tabBarController and the final ViewController. So you just have to set to hide the NavigationBarA
in viewWillAppear of your final ViewController you can add the following (without a need to subclass tabBarController)
self.tabBarController?.navigationController?.setNavigationBarHidden(true, animated: false)

how to nest NavigationController->TabBarController-> {NavigationController, NavigationController}

(Question in iOS7)
I know it is not good to put TabBarController in a NavigationController. But, is there any solution if it's really needed?
The stroyboard is like "This".
Here's the problem:
In 'ItemTVC', the backBarItem will not pop to its parent 'SampleTVC', but to root 'ProjTVC', why?
In 'SampleTVC', if called: [self.navigationController setNavigationBarHidden:NO] And [self.navigationController.navigationController setNavigationBarHidden:YES] to hide the root navigation bar and show the nearest ancestor navigation bar, how to set nearest ancestor navigation bar's leftBarButtonItem to backBarButtonItem of the root's navigationItem?
If both navigation bar are not hidden, the root navigation bar will dominate (be shown on top of nearest ancestor navigation bar. But, how to add a rightBarButtonItem to the root navigation bar? I tried: UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)] and self.navigationItem setRightBarButtonItem:addButton, but no button is shown.
Setting self.navigationController.backBarButtionItem never has any effect to its subsequent navigated views. It is always nil.
It seems to me that self.navigationItem get completed messed up when TabBarController and NavigationController are mixed in this configuration.
(An ugly solution I'm using is: hide the root navigation bar first, then assign a UIBarButtonItem to nearest ancestor navigation bar's leftBarButtonItem, then call [self.navigationController.navigationController popViewControllerAnimated:YES], but this button will be a different style as a 'backBarButtionItem' should be. How to get a copy of the currently displayed backBarButtionItem in a different navigation bar's item?)
You really shouldn't be doing any of this, both from an architecture standpoint and a UX standpoint. But... You don't need the second set of navigation controllers. They should use the push and pop of the root navigation controller just fine. Tab controllers in Nav controllers is bad. But Nav controllers inside tab controllers inside nav controllers is worse.
Edit:
If you want to fix the navigation items, you need to set them on the Tab Controller. It is the "current" view controller on the navigation controller and so it's navigation items will be what are shown on the navigation bar.
Thank you for your tips. I've removed the navigation controller. Now it can segue properly. (Question 1 is solved).
Regarding to missing RightBarButton, I actually solved by adding self.navigationItem.rightBarButtonItem = addButton; to the customized tabBarController's viewDidLoad first, then in tabBarController's sub-controllers, add
if (self.tabBarController) {
self.tabBarController.navigationItem.rightBarButtonItem = addButton;}
else{self.navigationItem.rightBarButtonItem = addButton;
}
This is really tricky to find that self.navigationItem is actually hidden when it's inside a tab controller. The real shown navigationBar is actually from self.tabBarController.navigationItem

navigationItem backBarButtonItem title

Having a issue with navigationItem backBarButtonItem title on a embedded UIViewController.
Im embedding UIViewControllers in scrollview for pagination, and i want to change the back button title for localization when i push something on the stack of scrollview / pagination controller.
This is the code im trying to do in didSelectRowAtIndexPath:
QueryItemTableViewController *itemView = [self.app.storyboard instantiateViewControllerWithIdentifier:#"QueryItemView"];
self.scrollcontroller.navigationItem.backBarButtonItem.title = #"Test";
[self.scrollcontroller.navigationController pushViewController:itemView animated:YES];
The view QueryItemTableViewController is correctly pushed to the navigationcontroller but the title of the back button is still the title from the previous view.
Any suggestions?
Could you please update the title in ViewDidLoad method of the UIViewController which is being pushed.
Set the navigation title in the first one..
As you push to the next view controller. The back button gets set automatically, with the title you have set for the previous.
Now update the Title of the present view controller in the ViewDidLoad .
So simply these are the steps:
Step 1
always set the title for the current view controller in ViewDidLoad to keep uniformity.
step 2
push to the next UIViewController. Everything gets set automatically.
N.B: You wont get any back button for the first view controller (since it is the root view controller). If you need a back button type button there, simply customise a UIBarButtonItem and use it.
The title of the back button will automatically adjust for localization based on the user’s device language settings.

ios navigation bar right button item shifts when pushing new view controller

I have a stack of three VCs that are coordinated through a navigation controller and make use of a navigation bar. On this navigation bar, in each VC, I added the same button (a 'Logout' button) as a right bar button item:
UIBarButtonItem *logoutButton =
[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"LogoutButtonTitle", #"")
style:UIBarButtonItemStyleBordered
target:self
action:#selector(logout)];
[categoriesViewController.navigationItem setRightBarButtonItem:logoutButton];
[[self navigationController] pushViewController:categoriesViewController animated:YES];
So each view controller has this logout button in the navigation bar. When I push any of these controllers onto the navigation stack, the new view controllers loads as expected, everything is displayed and functions correctly, but right after the new view controller is displayed (after the animation finishes) the logout button shifts about 3px to the right.
I've tried adding the button before pushing the VC, in the init methods of the VC, in the viewDidLoad and viewDidAppear but still the same behavior. I can't seem to get rid of this shift.
What's strange is that the back button disappears and reappears when pushing the new VC (using the default animation) but the 'Logout' button seems to stay in place and just shift to the right after the animation finishes. Also, the font on the buttons is not the default font but one of the system fonts (Helvetica light), may be related to this.
Any ideas on why this is happening?
I had the same problem. It is because of your rootviewcontroller not being set. Set the main page or the first page where your first navigation bar would be originating as rootviewcontroller. From there [self.navcontroller] pushviewcontroller...].
Try calling
self.navigationItem.rightBarButtonItem = yourUIBarButtonItem;
Also what is your logout button, is it the correct class? Perhaps a little more code?

Resources