I have an iOS app where there is a navigation controller as the root controller but at one part there is a tab bar to select between views in one of the nav bars. It looks similar to the iTunes app (navigation bar on top, tab bar on the bottom). I want the title of my navigation bar to change based on which tab is selected. I have two separate controller files for each tab. Here is what I have tried to use in each so far to fix this to no avail:
self.navigationItem.title = #"Title";
self.navigationController.navigationItem.title = #"title";
[self.navigationController setTitle:#"Live"];
[self setTitle:#"Top Title"];
How do I change the NavBar title based on which tab is pressed?
You change the title of the bar in the view controller that is currently being displayed.
So for example, in view controller A that you're showing in the tab controller, you might add:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self setTitle:#"A"];
self.tabBarController.navigationItem.title = #"A";
}
Same goes for B, C, etc.
In your ViewControllers that are in the tabs:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.tabBarController.title = self.title;
}
If the individual view controllers presented by the tab bar controller have their own navigation bars, then
[self setTitle:#"Foo"];
will set both the tab bar label, as well as the navigation bar title.
If the navigation controller is at the top level (i.e. the tab bar is inside the navigation controller), then you might have to set the navigation bar title's manually (and you'll want to do this in viewDidAppear rather than viewDidLoad, because these child controllers are not reloaded every time you switch), e.g.:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.navigationController.navigationBar.topItem setTitle:#"Foo"];
}
Alternatively, you could do this navigation bar title adjustment in your UITabBarControllerDelegate method didSelectViewController.
If this doesn't do it, you might have to clarify your question, describing the hierarchy of controllers (e.g. is the tab bar controller inside navigation bar, or vice versa).
You can subclass the UITabBarController, set the delegate to itself, and use the delegate to set its title when the view controller is selected:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
//change the title based on viewController that is selected
self.title = #"New title";
}
Just Two Lines of Code..Only thing is, you need to use viewWillAppear method
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tabBarController.navigationItem.title = #"Your Title";
}
PS: Inspired from Above Answers...
UITabBarController *tabController = (UITabBarController *)self.parentViewController;
tabController.navigationItem.title = #"ABC";
This is working for me
From some R&D on internet
You have to pass the navigationItem up the chain.
The UINavigationController shows the navigationItem belonging to its topViewController which is UITabBarController.
The UITabBarController shows the navigationItem titles in its tabs. So what you need to do is make sure that the tabBarController's navigationItem is it's selectedViewController's navigationItem
So to recap:
UINavigationController title = topViewController.navigationItem.title
UITabBarController tabTitle =
selectedViewController.navigationItem.title
UIViewController title = navigationItem.title
Related
I have a tab bar controller with four tabs. For one tab, i have created a new storyboard with navigation view controller and simple UIViewController. For other tabs, connected view controllers with navigation controller within the same storyboard.
When i try to launch first view controller from new storyboard from first tab, it is not showing tab bar. for others it is showing tab bar properly.
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
NSInteger index = [tabBar.items indexOfObject:item];
if(index == 0){
UIViewController *suggestionsViewCintroller = (UIViewController *)[[UIStoryboard storyboardWithName:#"suggestions_view" bundle:nil] instantiateViewControllerWithIdentifier:#"suggestions_view_controller"];
[self addChildViewController:suggestionsViewCintroller];
[self.view addSubview:suggestionsViewCintroller.view];
suggestionsViewCintroller.hidesBottomBarWhenPushed = NO;
[suggestionsViewCintroller didMoveToParentViewController:self];
}
}
Navigation controller configuration in storyboard :
View controller and tab bar controller are in different storyboards.
Why is it not showing tab bar in view?
I don't think that is the proper way to add a view controller to the tab bar. I think you want to sub class your UITabBarController and add the new view controller to the UITabBarController sub class in the viewDidLoad method of the sub class. You can see an example of this here. The main code is added in TabBarController (a sub class of UITabBarController)
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController* naviController = [[UIStoryboard storyboardWithName:#"Other" bundle:nil]
instantiateViewControllerWithIdentifier:#"NavigationController"];
naviController.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Suggestions"
image:[UIImage imageNamed:#"suggestions"] tag:2];
self.viewControllers = [self.viewControllers arrayByAddingObject:naviController];
}
Edited the example to use 2 different storyboards.
Main storyboard:
Other storyboard:
Video here.
Calling 'addChildViewController' you do not add tab in UITabBarController.
This call just add child view controller over whole view of UITabBarController. So it is quit reasonable, that you can not see tabbar.
If you wish to add view controller as TAB of UITabBarController, you should use 'viewControllers' property as shown here:
https://stackoverflow.com/a/11399634/4322841
And should maybe use 'selectedIndex' property.
How to let child view controller modify navigation controller?
I am faced with this problem right now, and have not been able to find a solution that works, let alone one that works well.
Basically, right now I have a UINavigationController that contains a UITableViewController with a search bar in the navigation bar. So far so good - everything works well.
However, I would like to show some custom views between the navigation bar and the top of the table view at times. To do this, I figured it would be best to create another view controller (let's call it the ContainerViewController), which is presented by the navigation controller. This container view controller holds the table view controller as a child, and can insert any custom view it wishes to. The view controller hierarchy should look like this:
UINavigationController
ContainerViewController
UITableViewController (with UISearchDisplayController)
Now I am faced with a problem, since the search bar of the UISearchDisplayController should be displayed in the navigation bar (by calling didSetupSearchDisplayController), but I obviously want all logic pertaining to it kept in the UITableViewController. I need the container view controller to sort of act as a go-between here. I have tried to figure this out, but haven't managed a solution yet.
Here is how I instantiate the table view controller and add it as a child in the container view controller.
- (void)viewDidLoad {
[super viewDidLoad];
// Load view controller from storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
self.contentViewController = [storyboard instantiateViewControllerWithIdentifier:#"MyListViewController"];
self.contentViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
// Add its view to the content view
[self addChildViewController:self.contentViewController];
[self.container addSubview:self.contentViewController.view];
[self.contentViewController didMoveToParentViewController:self];
// Set up constraints
[self.contentViewController.view autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];
}
In the child view controller, I have noticed that self.navigationController is nil in viewDidLoad but not in didMoveToParentViewController. So the following works:
- (void)didMoveToParentViewController:(UIViewController *)parent {
// Hide separator below navigation bar
self.navigationController.navigationBar.clipsToBounds = YES;
}
But I cannot set the search bar to display in the navigation bar, nor can I set the navigation bar title (with self.title = ...) from within the child view controller.
Would appreciate any help.
EDIT: Here is some code I use in the UITableViewController (the contained view) to create the search display controller:
UISearchBar *searchBar = [[UISearchBar alloc] init];
self.mySearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
// Show search bar in navigation bar (instead of in its own bar underneath)
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
// Set self as delegate to search display controller and its table view
self.searchDisplayController.delegate = self;
self.searchDisplayController.searchResultsDelegate = self;
I have tried doing this both in viewDidLoad, where the self.navigationController is nil, and in didMoveToParentViewController, where the navigation controller exists, but it does not seem to matter. My guess is that the displaysSearchBarInNavigationBar magic happens after the child view is instantiated but before it is added as a child view (and thus gets access to the navigation controller).
can you use
self.parentViewController.navigationController
to get the reference to the navigation controller from within the container view?
This may help you find your answer. We use this to set the title of our navigation controller
self.navigationItem.title=#"Name of view goes here";
You should be able to use self.navigationItem to get a handle to the navigation bar.
I have a NavigationController then a TabBarController which has Four Tabs.
I wanted to display Different titles on TopBar when a Different Tab is selected.
One way was to Embed each TabBarItem View into Navigation Controller but for some reason this doesn't seems the correct way, i wanted to apply this via code.
I managed accomplish this by using this code: (Products_ViewController.m custom class)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
But the problem is now when a tab is clicked First time, it changes the title but then it doesn't. I then applied the same code on -(void)viewDidAppear{} but still the same result.
How can i manage to display navigation top bar title (or run the above code) whenever the tab bar item is clicked or the view is shown?
Thanks!
You could implement the UITabBarControllerDelegate in the Products_ViewController.m class and execute your code in the tabBarController:didSelectViewController: method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
In the viewDidLoad method you have to set the delegate to self.
When pushing a view controller my toolbar buttons fade out and then in again with the new view. The problem is that i have the same buttons in the next view as the previous so it looks like the buttons do a quick flash when switching screen. My question is if this can be avoided by disable the fade out of toolbar buttons for the navigation controller when pushing to a new view or if the toolbar can be bound to the navigation controller in such a way that it is the same for all views. The last suggestion since i have seen that my navigation bar buttons does not fade out when pushing a new screen.
I'm surprised that nobody answered you. I've just faced this issue, and here's a solution I've found.
Subclass your navigation controller
Override you push/pop methods
-(UIViewController*)popViewControllerAnimated:(BOOL)animated
{
self.navigationBarHidden = YES;
UIViewController *vc = [super popViewControllerAnimated:animated];
self.navigationBarHidden = NO;
return vc;
}
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
self.navigationBarHidden = YES;
[self pushViewController:viewController animated:animated];
self.navigationBarHidden = NO;
}
It did the trick for me.
I know this question is old, but there is a simple solution: Set both controller's navigation items to the same bar button item, and it won't animate. Eg:
UIBarButtonItem* item = [[UIBarButtonItem alloc] initWith...];
viewController1.rightBarButtonItem = item;
viewController2.rightBarButtonItem = item;
If you now push viewController2 after showing viewController1, the navigation item will not animate.
For building up a toolbar in the code, I think it should be in the ViewWillAppear lifecycle method. I had previously built up a toolbar in code but in ViewDidLoad, and I saw this quick fade in/fade out
My app is based on a tab bar architecture. In order to have an easy internationalisation mechanic, I do not write any string in XIB files. viewdidload permits to change programmaticaly the strings in the views.
When my app launches, I can see the 4 tabs. But in fact only the first one loads its view controller. The others wait for user click to be loaded.
Tabs title can be changed using [self setTitle:#"Mouhahaha"]; in viewDidLoad of loaded view controller.
If I want to keep my internationalisation mechanic available, I do not set in my XIB the name of tabbar items. But, as at start all tab' view controllers are not loaded, I have blank titles for some tabs. The right title is set only when the user click on the tab.
I am looking for a way to set this title programaticaly for each tabbaritem. Do you have hints ?
Thanks a lot.
kheraud
my preferred method of doing this programmatically together with the storyboard is to make a subclass of UITabBarController, have my tab bar controller scene in my storyboard use the new subclass (with 3 UIViewController relationships from the tab bar controller to the desired view controller in the case below), and then override viewWillAppear:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSArray* titleKeys = [NSArray arrayWithObjects:#"top places",
#"localizablekey1",
#"localizablekey2",
#"localizablekey3",
nil];
[super viewWillAppear:animated];
int count = 0; for (UIViewController* viewController in self.viewControllers)
viewController.tabBarItem.title = NSLocalizedString([titleKeys objectAtIndex:count++], nil);
}
All you need to do is make an instance of UITabBarController, then alloc any views you want in it, then set the UITabBarController views. Make sure that your TabBarController is the one that is visible. Also make sure that any viewControllers you want in your tab bar are being imported with #import.
UITabBarController *c = [self tabBarController];
SecondViewController *s = [[SecondViewController alloc] init];
[s setTitle:#"Whatever"];
c.viewControllers = [NSArray arrayWithObjects:self, s, nil];
[s release];
Put this in the viewDidLoad method of the first controller allocated.
Alternatively you could just change the way your ApplicationDelegate sets up the TabBarController, but i won't go into that.
Hope this helps