how to add tabbarcontroller in a navigation controller - ios

I need to have a tabbar kind of view in a view controller(say view controller 3) which is in navigation stack and will be pushed by another view controller (say view controller 2).
I added tool bar to view controller 3 with many buttons. But managing and switching between views seems difficult.
How can i add a tabbar controller in the middle of navigation stack.
please help me out.

You cnt create tabbar in the middle of view controllers, you can create tab bar structure using custom segment controller. check the link below for creating custom segment controller.
https://www.cocoacontrols.com/search?q=segment

You cannot add TabBar there - tabBar is only designed to be at the bottom.
You have to create your own ViewController and add it as subView for navigationViewController and implement whole switching methods.

There has been some discussion about this design in related questions.
The way I understand your question it's definitely possible though. I am pushing a UITabBarController onto a UIViewController that is embedded in a UINavigationController. I did everything in the interfacebuilder except for the push which I implemented programmatically.
So in ViewController.m I added an action to a button:
- (IBAction)searchForPlacesButtonPressed:(id)sender {
TabBarController *tc = [[self storyboard] instantiateViewControllerWithIdentifier:#"TabBarController"];
tc.title = #"Orte";
tc.tabBar.selectedImageTintColor = [UIColor colorWithRed:(28.0f/255.0f) green:(100.0f/255.0f) blue:(52.0f/255.0f) alpha:1.0f];
UIBarButtonItem * logo = [[UIBarButtonItem alloc] initWithCustomView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon_xyz"]]];
tc.navigationItem.rightBarButtonItem = logo;
Places *d = [[Places alloc] init];
for (UIViewController *vc in tc.viewControllers) {
if ([vc isKindOfClass:[MapViewController class]]) {
((MapViewController *)vc).dataHandler = d;
((MapViewController *)vc).mapViewDelegate = d;
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Karte" image:[UIImage imageNamed:#"map"] tag:0];
}
else if ([vc isKindOfClass:[TableViewController class]]) {
((TableViewController *)vc).dataHandler = d;
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Liste" image:[UIImage imageNamed:#"eye"] tag:1];
}
}
[self.navigationController pushViewController:tc animated:YES];
}
Using the tabs at the bottom you can switch between viewing the places on a map and listed in a table.

Related

How to toggle view controllers using a UITabBar?

My goal for this project is to cycle between View Controllers using a UITabBar, without a UITabBarController, because according to Apple docs, TabBarControllers should not be pushed to UINavigationControllers, which this project uses already.
So far, I am using this UITabBar from #samuel's answer from this question. How to add UITabBar in iphone using objective c
//viewDidLoad
...
UITabBar *tabBar = [[UITabBar alloc] initWithFrame:CGRectMake(0, 431, 320, 50)];
[self.view addSubview:tabBar];
[[UITabBar appearance] setBarTintColor:[UIColor blackColor]];
NSMutableArray *tabBarItems = [[NSMutableArray alloc] init];
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Home" image:[UIImage imageNamed:#""] tag:0];
UITabBarItem *tabBarItem1 = [[UITabBarItem alloc] initWithTitle:#"Rules" image:[UIImage imageNamed:#""] tag:1];
[tabBarItems addObject:tabBarItem];
[tabBarItems addObject:tabBarItem1];
tabBar.items = tabBarItems;
tabBar.selectedItem = [tabBarItems objectAtIndex:0];
}
I am ready to cycle between View Controllers when I press the tabBarItems. What is the correct way to do this? I want to go to a View Controller named ViewController9 when the Rules tabBarItem is tapped, and then to ViewController6 when the Home tabBarItem is tapped.
Can someone please share some code? Here's what I've tried but nothing happens when the tabBarItems are pressed:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
NSInteger selectedTag = tabBar.selectedItem.tag;
NSLog(#"%ld",(long)selectedTag);
if (selectedTag == 0) {
//Do what ever you want here
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"ViewController9"];
[self presentViewController:vc animated:YES completion:nil];
} else if(selectedTag == 1) {
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"ViewController9"];
[self presentViewController:vc animated:YES completion:nil];
} else { //if(selectedTag == 2)
//Do what ever you want here
}
}
How to push a view controller using a UITabBar using Objective C?
That question doesn't make much sense if you think about it. "Push" is a stack operation, and a navigation controller manages a stack of view controllers. UITabBar isn't a view controller at all, and it doesn't manage a stack of anything, so pushing isn't an operation that's available.
My goal for this project is to cycle between View Controllers using a UITabBar, without a UITabBarController, because according to Apple docs, TabBarControllers should not be pushed to UINavigationControllers, which this project uses already.
There's a reason for that, and the reason is that navigation controllers and tab controllers offer different modes of controlling what the user sees on the screen. If a tab controller could be part of a navigation stack, the user would see the tab bar appear and disappear, when it's intended to be something that's fixed. It would create a very confusing interface.
If you use a tab bar alone to get around the fact that Cocoa Touch discourages you from creating a confusing user interface, you're going to end up with a confusing user interface. Think hard about what you're really trying to do, and if you decide you still need to do it, consider using UI elements that don't look like a tab bar so that the user doesn't expect tab bar behavior.

pushViewController not working after back

For my code structure:
On AppDelegate, I declared 4 UINavigationController with their own root UIViewController for my UITabBar.
I created one custom UIViewController as template, in where my other UIViewControllers are sub-class.
On my template:
I have my rightBarButtonItem to show current user profile.
// public method added on template
- (void) goToProfile {
NSLog(#"going through...");
ProfileViewController *ctrl = [[ProfileViewController alloc] init];
[self.navigationController pushViewController:ctrl animated:YES];
}
For my leftBarButtonItem:
- (void) goBack {
[self.navigationController popViewControllerAnimated:YES];
}
First click on the rightBarButtonItem, works fine. If I click the leftBarButtonItem to go back then re-click the rightBarButtonItem, it won't work anymore.
In addition, I have a button on one of my UIViewController that is calling the public method goToProfile. And that works fine.
I got help from my co-worker. The approach is something similar to #Vidhyanand900 answer. I hope this will help others in the future.
tabbarSelectedIndex = 1; // profile tab index
ProfileViewController *ctrl = [[ProfileViewController alloc] init];
UINavigationController *navController = [_appDelegate.mainTabBarController.viewControllers objectAtIndex:tabbarSelectedIndex];
[navController pushViewController:ctrl animated:YES];
self.mainTabBarController.selectedIndex = tabbarSelectedIndex;
If you are pushing or popping with UINavigation controllers of UITabBar
Else show UINavigation Controllers inside UITab Bar..i.e; Is Profile View controller is part of UITab bar or not..
Then you need to change the index of tab bar as below
self.tabBarController.selectedIndex=0;//if profile is first tab
ProfileViewController *ctrl = [[ProfileViewController alloc] init];
[self.navigationController pushViewController:ctrl animated:YES];
Hope it helps you...

load page with pushViewController on tabbar

I have UIViewController with tabbar botton, and navigation bar and navigation item,
when I press on my button in navigation Item I want to load a view, I don't know how to load this view on tabbar,
would you please help me,thanks in advance!
-(IBAction) infoPage:(id)sender
{
InfoCtrol *i = [[InfoCtrol alloc] initWithNibName:#"InfoCtrol" bundle:nil];
[self.navigationController pushViewController:i animated:YES];
}
This will load the InfoCtrol controller and set the Touch UpInside Event in xib to the infoPage method
Do you mean you want to hide the tab bar when you push new controller in navigation?
If true. There is a property hidesBottomBarWhenPushed in the UIViewController class.
// Instead of adding ViewController to TabbarController, add NavigationControllers.
// Eg.
UINavigationController *NavController = [[UINavigationController alloc] initWithRootViewController:_viewCtrl1];
[watchListNavController.navigationBar setTintColor:[UIColor blackColor]];
_tabC = [[UITabBarController alloc] init];
_tabCt.viewControllers = [NSArray arrayWithObjects:NavController,_viewCtrl2,_viewCtrl3, nil];
// Now you can use Push and Pop In your _viewCtrl1.
// Do same with all the viewController

Landscape UISplitViewController when using a UINavigationController in the detail

I am developing an iPad/Universal application, and I am facing the problem of handling a UINavigationController as the main detail view in a UISplitViewController. What I want to know is how to add the default side controller button to the detail controller when in landscape orientation.
Definition
The split view controller has been defined this way:
splitViewController = [[UISplitViewController alloc] init];
SideController *root = [[[SideController alloc] init] autorelease];
DetailController *detail = [[DetailController alloc] init];
InserisciDatiController *calcolo = [[[InserisciDatiController alloc]
initWithNibName:#"InserisciDatiNuovi"
bundle:[NSBundle mainBundle]]
autorelease];
UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:root]autorelease];
UINavigationController *calcoloNav = [[[UINavigationController alloc] initWithRootViewController:calcolo] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, calcoloNav, nil];
splitViewController.delegate = detail;
and later on I release all the releasable objects.
I am using the SideController as a sort of index for the detail controller. It has a table view, and clicking each row I update the main view controller of the detail. Each new controller is always an instance of UINavigationController.
Update the detail
myAppDelegate *delegate = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
UINavigationController *nav = (UINavigationController *)[delegate.splitViewController.viewControllers objectAtIndex:1];
[nav setViewControllers:[NSArray arrayWithObjects:controller, nil]];
I use this piece of code to update the detail controller, when the user taps a row in the side view controller.
Handle landscape orientation
I'd like to know how to handle the landscape orientation, when I want to add the default toolbar button to display the hidden side view controller. What I am not able to do is getting the toolbar of the detail navigation controller to add the button using this method:
- (void)splitViewController:(UISplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc
And also, when I push a new controller to the navigation controller the default back button will appear in the toolbar. In this case how should I handle the button creation?
Update
Please, do not tell me that no-one has ever had this kind of problem! How do you develop iPad apps? Sob ...
I found a way that could be useful for someone, even though I do not really think this is a clean way of handling the navigation controller.
In the split view controller delegate I implemented the splitViewController:willHideViewController:withBarButtonItem:forPopoverController: method this way:
- (void)splitViewController:(UISplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc
{
barButtonItem.title = NSLocalizedString(#"menu", nil);
myAppDelegate *app = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
UINavigationController *nav = [app.splitViewController.viewControllers objectAtIndex:1];
UIViewController *ctrl = [nav.viewControllers objectAtIndex:0];
if (!ctrl.navigationItem.backBarButtonItem && !ctrl.navigationItem.leftBarButtonItem) {
ctrl.navigationItem.leftBarButtonItem = barButtonItem;
}
}
Here I present the bar button item that will show the popover view representing the side view controller if and only if the navigation controller is not showing the back button or another custom left button item.
Hope this helps someone!
I believe that Slava Bushtruk of Alterplay has worked out what you're looking for and used it in his APSplitViewController library.
I think the reason you haven't gotten any good answers is that it's really hard to understand your problem, i.e., your question could be clearer.
So first let me see if I've understood the problem correctly. Is the problem that you don't know how to handle the case when you've pushed something on your navigation controller and is supposed to show both the back button and the split view button?
If so, the way we've solved that problem is that the split view button is only visible in the root of the navigation controller. The side controller is usually only relevant for the detail view's root view controller anyway.
If I've misunderstood your problem or my solution isn't applicable to your project, please let me know.
EDIT: So if you insist on doing this, here's a way to do it:
toolbar = [[UIToolbar alloc] initWithFrame:(UIInterfaceOrientationIsPortrait(interfaceOrientation)) ? CGRectMake(0, 0, 768, 44) : CGRectMake(0, 0, 703, 44)];
toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.navigationController.navigationBar addSubview:toolbar];
On viewWillDisappear:
[self setToolbarHidden:YES animated:animated];
and on viewWillAppear:
[self setToolbarHidden:NO animated:animated];
Now you have a toolbar that you can add anything to. Well, anything that can be added to a UIToolbar anyway, which is almost anything.

How can I create a tab view programmatically on iOS

For an iPhone app how can I create a tab view programmatically, preferably in Objective-C?
It's quite simple to create a UITabBar via the UITabBarController. The following example should work within your AppDelegate class.
App Delegate Interface
Firstly, within the interface, we'll define our UITabBarController.
UITabBarController *tabBarController;
App Delegate Implementation
Then, within the implementation file's application:didFinishLaunchingWithOptions: method, we'll then initialise our tab bar controller.
// Initialise our tab bar controller
UITabBarController *tabBarController = [[UITabBarController alloc] init];
Next, you need to create the view controllers that you want to add to the tab bar controller. We'll need to add some information into these to set the tab's title/icon, but I'll come back to that at the end.
// Create your various view controllers
UIViewController *testVC = [[TestViewController alloc] init];
UIViewController *otherVC = [[OtherViewController alloc] init];
UIViewController *configVC = [[ConfigViewController alloc] init];
As the setViewControllers:animated: method requires an array of view controllers, we'll add our view controllers to an array and then release them. (As the NSarray will retain them.)
// Put them in an array
NSArray *viewControllers = [NSArray arrayWithObjects:testVC, otherVC, configVC, nil];
[testVC release];
[otherVC release];
[configVC release];
Then simply provide the UITabBarController with the array of view controllers and add it to our window.
// Attach them to the tab bar controller
[tabBarController setViewControllers:viewControllers animated:NO];
// Put the tabBarController's view on the window.
[window addSubview:[tabBarController view]];
Finally, make sure you call [tabBarController release]; within your dealloc method.
View Controller Implementation
Inside each of your view controllers, you'll also want to set the title and icon for the tab within the init method as follows:
// Create our tab bar item
UITabBarItem *tabBarItem = [self tabBarItem];
UIImage *tabBarImage = [UIImage imageNamed:#"YOUR_IMAGE_NAME.png"];
[tabBarItem setImage:tabBarImage];
[tabBarItem setTitle:#"YOUR TITLE"];
This is how we have to create tabbar programmatically
UINavigationController *BandNavigationController3;
AudienceSettingsViewController *audienceSettingsViewView =[[AudienceSettingsViewController alloc]initWithNibName:#"AudienceSettingsViewController" bundle:nil];
BandNavigationController3 = [[UINavigationController alloc]initWithRootViewController:audienceSettingsViewView];
BandNavigationController3.tabBarItem.title = #"Settings";
BandNavigationController3.tabBarItem.image = [UIImage imageNamed:#"settings.png"];
[BandNavigationController3.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemFavorites tag:4];
BandNavigationController3.navigationBar.hidden = YES;
[bandTabBarArray addObject:BandNavigationController3];
[BandNavigationController3 release];
[audienceSettingsViewView release];
[tabBarController setViewControllers:bandTabBarArray];
[bandTabBarArray release];

Resources