Im having difficulty getting the titles of the navigation bars to display along with the buttons within my tabBarController interface. Im creating the tabBarController programmatically. Here is the screenshot for reference.
I have tried putting self.navigationController.navigationBarHidden = YES; within the alloc/init method of the tabBarController which is allocated in the appDelegate and set as the windows rootViewController. I've also tried to set its title with this code self.navigationController.title = [[self.viewControllers objectAtIndex:self.selectedIndex]title ];. I have also tried using the same code within the viewDidLoad method of my tabBarController class. Within the UITabBarController's alloc/init method I do have this code to set the nav controllers that I have added to the viewControllers array.
UINavigationController *nav2 = [[UINavigationController alloc]initWithRootViewController:contactsTblView];
nav2.title = #"Contacts";
nav2.navigationItem.title = #"Contacts";
nav2.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts tag:2];
nav2.delegate = self ;
The title that appears in the navigation bar is the title of the currently showing view controller (the top of the navigation controller's stack). You should set the title of the individual view controllers embedded in the navigation controller, not the navigation controller itself.
Related
I've a UIViewController which loads it's view form a Xib file. In my AppDelegate.m I would like to initiate my rootViewController with that myViewController and I would like that the title of the navigtionItem is set by taking the NavigationBar view which is part of the Xib file of the myViewController:
MyViewController *myViewController = [[MyViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
According to the documentation
Each time the top-level view controller changes, the navigation controller updates the navigation bar accordingly.
In my setup this seems not to happen or I haven't indicated that my NavigationBar view is actually the navigationBar to consider.
How can I tell the NavigationController to update it's navigationItem content (title, left and right bar buttons) according the NavigationBar view which is part of the Xib file from myViewController?
Update
My Xib layout looks like this:
I know I can set those items in code by:
self.navigationItem.titleView = ...;
self.navigationItem.leftBarButtonItem = ...;
But I want them do design in the Xib file of the ViewController and they should be used in the NavigationController.
In ViewWillAppear method in your ViewController set-
self.navigationItem.title = #"Title name";
Also in the same way you can set self.navigationItem.leftBarButton and RightBarButton items
Adding a UINavigationBar view to the main UIView doesn't do what you think it does. It merely adds a navigation bar view there in the view, it does not tie into the UINavigationController.
If you use a storyboard, you can add the UINavigationItem as a child of the UIViewController. But since you are not using a storyboard, the easiest way to do it is to update the navigationItem in viewDidLoad.
Sidenote: Apple does not recommend using viewDidLoad to setup the navigation item. If you really want to do it the proper way, you can for example do it in the navigationItem getter.
- (UINavigationItem*)navigationItem
{
// get super navigation item
UINavigationItem *navItem = [super navigationItem];
// do stuff
return navItem;
}
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.
Adding tab bar controller to the UIView by [self.view addSubview:tabBarController.view];
is not loaded the content view controllers view, while selecting the tab bar items it crashed. When set the tab bar controller to the root view controller its working fine. How to set tab bar controller into UIView so that I can set another view for some other purpose like iAd?
You just create one tabbar controller in app delegate but don't add it to window, and in view controller you have just add these:
gObjAppDelegate.tabBarController = [[UITabBarController alloc] init];
gObjAppDelegate.tabBarController.viewControllers = #[viewController1, viewController2];
[gObjAppDelegate.tabBarController setSelectedIndex:0];
[self.navigationController pushViewController:gObjAppDelegate.tabBarController animated:YES];
gObjAppDelegate is shared singleton instance of app delegate.This way it worked for me.
I am creating a view controller that is pushed to the UINavigationController. I need a customized navigation bar, therefore I have overridden navigationItem method of my view controller. In a titleView (property of UINavigationItem) I need a custom view that holds two buttons. Question: how to apply view controller for those two buttons?
View containing two buttons is defined in CustomTitleViewController.xib, whereas its view controller is defined in CustomTitleViewController class.
This is my way of returning the navigation item (MainViewController.m):
- (UINavigationItem *)navigationItem
{
UINavigationItem *navItem = [[UINavigationItem alloc] init];
UIViewController *customTitleViewController =
[[CustomTitleViewController alloc] initWithNibName:#"CustomTitleViewController"
bundle:[NSBundle mainBundle]];
navItem.titleView = [customTitleViewController view];
return navItem;
}
The view is shown on the navigation bar, as expected. However, tapping the button crashes the application (EXC_BAD_ACCESS).
Error message: message sent to deallocated instance 0x6e53850.
Any ideas?
Basically, you need to retain pointer to viewController as well as to its view. Just create strong property on your UINavigation controller subclass. Coz what you are doing here is instantiating new controller each time navigation item is called and realising it at the end of the function. Here is a very quick crude fix:
https://www.dropbox.com/s/y6ltdyj951ioncd/Navigating.zip
be sure not to reinstantiate VC all the time and keep pointer to it.
Hope this helped.