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

(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

Related

Can't get default UINavigationController back button to work

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.

Tab bar controller inside a uinavigationcontroller

I have got a Tab Bar Controller inside a Navigation Controller but I cant seem to set the Navigation bar title or add a button to the navigation bar using:
self.title = #"My Name";
The code above only changes the Tab Bar Item name and not the navigation controller.
Secondly. I want to disable going back the login screen (The screen with the UIWebview over it in the screenshot)
EDIT: I found a possible duplicate
It's uncommon to put a tabBarController into a navigationController. If you can't find what's going wrong in your way try to use another way to approach what you want which is put navigationControllers into one tabBarController. Make tabBarController the initial view controller.
Not sure about the others but to set the title on the nav bar try this:
self.navigationController.navigationBar.topItem.title = #"My Title";
Although with the button in the nav bar just drag in a UIBarButtonItem from the side panel

UIBarButton unclickable in empty ViewControllers

i've created a tabBarController subclass and linked 3 viewcontrollers to the TabBarController in the storyboard. In the 3 ViewControllers which is directly connected with the tabBarController the UIBarButtons wont react when i click. They wont show the log message and does not do the highlight color. It seems like the navigationBar interaction is disabled or something. When i present a view modally on top of one of the 3 ViewControllers i have no problem with interaction with a UIBarButton in the modally presented View. I'm wondering what could result in such? i've struggled with this for ours.
i don't know if this has anything to do with it aswell, but in the modally presented views this does also result in white statusBar textColor, but it does not change it in the 3 views connected to the TabBarController.
What could this issue be?
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.translucent = NO;
i've simply manually added a UIBarButton in the storyboard and then connected this action.
-(IBAction)testAction :(id)sender {
NSLog(#"test");
}
Try this
You just take 3 Navigation Controller as your tab bar view controller rather than simply view controller.
And connect tab bar view controller with navigation controller.
On navigation controller there is one view controller, on that navigation bar put your bar button item and connect to IBAction Method.
Its works for me.

Navigation bar button unresponsive in child view controller of UITabBarController

I instantiate my UITabBarController by calling navigationController.viewControllers = #[[self.storyboard instantiateViewControllerWithIdentifier:#"tabController"]];
My Tab bar controller has a child view that is embedded in a navigation controller. However the bar button (item) is unresponsive when I touch them (the buttons in the navigation bar). I have tried logging the action but it appears as if the button is not firing at all.
The only thing that I have done differently is the way i instantiated the tab bar controller. Am I missing something?
I connected the navigation bar button from the storyboard to an action so it is hooked up successfully. Please note there is also a navigation Controller pointing to the UITabbarController not shown below.
The unwanted behaviour maybe because this flow (navigation controller to tabbar controller) is ill advised in the Apple HIG. More information can be found here: Storyboard with NavigationController and TabController. The solution I found was to hide the navigation bar on the navigation controller that links to the navigation bar (can be done in interface builder), then make it reappear in the new navigation controller that the tab bar links to. Confusing I know, I can help anyone who ever has a similar issue.
Is there any specific reason you are doing this:
navigationController.viewControllers = #[[self.storyboard instantiateViewControllerWithIdentifier:#"tabController"]];
You can simply drag an outlet from the UITableViewController to the UINavigationController using only the Storyboard.
I think you forgot to add the navigationItem. In the storyboard, add a navigation Item to your viewController and move your bar button items to the navigation bar that appears on the top.

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