I have a Tab-bar application in iOS Storybords. The UITabbarcontroller is connected to -->4 sets of (UInavigation controller--> UItableview controller). Each UITableviewcontroller cells are connected to multiple UIviewcontrollers to be pushed.
On building the app -The navigation tab appears on the top of the view controllers without any problem. But the Tabbar with 4 items at the bottom is visible ONLY on the first view. The UIviewcontrollers does not display the 4 item Tabbar!??. I have set the bottom bar to tab bar in the attributes inspector. But it doesn't work?
I believe there must be more to it than I understand. Hope somebody helps.
How to display the tabbar through out the app?
I'm not totally sure of your design, but here are a couple of tips that hopefully may help.
storyboard design:
basic tabbar application layout would generally look like this from left to right with the first controller on the left having the little arrow indicating it is the starting controller.
your first controller should be the tabbar controller
each tab should be connected to a navigation controller
each navigation controller should be connected to one or more UIViewControllers or UITableViewControllers.
now, note while there are advanced configurations, this is just the general layout that sets up the app nicely and gives easy push transitions for each tab.
if your app starts off and shows the tabbar and when you select a tab item it should show the view controller for that tab. if the tabbar is still there, then you are in good shape up to that point. If you select something on that view controller and it pushes a new view controller on screen and when that happens you lose the tabbar bar, then its likely this is the issue:
- check your view controllers and look in the object inspector for a check mark called "hides bottom bar on push" - if it is checked - then uncheck it.
If you don't find it there, then inspect your code for your view controllers and look in the startup methods like view did load for the statement: self.hidesBottomBarWhenPushed = YES; if you find that command, comment it out or delete it.
It is perfectly ok to hide the tabbar on some view controller pushes if that is your design and makes sense in your application. Generally, it's a good practice to try and avoid it and leave the tabbar on screen when possible for user experience but sometimes issues like screen size might lead the developer down a path of hiding it for some workflow.
I hope this helps and ties back to your question. if not, sorry.
You can add tab bar like this way:-
Appdelegate.h
#import <UIKit/UIKit.h>
#class StartingViewController;
#interface Appdelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
StartingViewController *viewController;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet StartingViewController *viewController;
#property (nonatomic,retain) UITabBarController *tabBarController;
-(void)addTabBarToView;
#end
app delegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[self addTabBarToView];
return YES;
}
-(void)addTabBarToView{
FirstController *first = [[FirstController alloc] initWithNibName:#"FirstController" bundle:nil];
first.title = #"First";
SecondController *second = [[SecondController alloc] initWithNibName:#"SecondController" bundle:nil];
second.title = #"Second";
ThirdController *three = [[ThirdController alloc] initWithNibName:#"ThirdController" bundle:nil];
first.title = #"Third";
Forthcontrooler *Four4 = [[Forthcontrooler alloc] initWithNibName:#"Forthcontrooler" bundle:nil];
second.title = #"Secfor";
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:first];
UINavigationController *navigationController2 = [[UINavigationController alloc]initWithRootViewController:second];
UINavigationController *navigationController3 = [[UINavigationController alloc] initWithRootViewController:three];
UINavigationController *navigationController4 = [[UINavigationController alloc]initWithRootViewController:Four4];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController1,navigationController2,navigationController3,navigationController4,nil];
[window addSubview:tabBarController.view];
}
Put the UINavigationControllers inside the UITabbarControllers instead of the other way around
Related
I have been searching and experimenting on this for a while, but I just can't find out what I'm doing wrong.
I want to make an app with a menu, and from that menu, you can get to a TableViewcontroller with a title bar. I found out that, in order to get this title bar, you need to "insert" UITableViewController into a UINavigationController. this is where I'm stuck.
let's not mind / forget the menu from the app for now, because i know how to switch view controllers when user taps a button.
in my AppDelegate.m I have:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
TableViewController *tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
self.navController = [[UINavigationController alloc] initWithRootViewController:tableView];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
in my AppDelegate.h file I Have:
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
UINavigationController *navcontroller;
}
#property (strong, nonatomic) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
I have 2 classer, UITableViewController and NavigationView.
In the UITableViewController, I made an array called tableRows:
tableRows = [[NSArray arrayWithObjects:#"1", #"2", nil] init];
the numberOfSectionsInTableView is set as 1 and the numberOfRowsInSection is set as return tableRows.count;
I left my NavigationView.m untouched, except that I tried to set a title in it.
in my NavigationView.xib, I tried to make the connection between the UITableViewController and the UINavigationController.
I added an NSObject, and changed its class to AppDelegate
I replaced the View for a UIWindow and connected the window property from my
AppDelegate.h to it
I added a UINavigationController and
connected it with the navController from my AppDelegate.h.
and last, I changed the class from the RootView from the
UINavigationController to UITableViewController.
Now my problem is, with or without the connections in IB, whatever I try to change in my table, or in the titlebar, it does not change when I run the app.
Does anybody know what I'm doing wrong? I'm using xcode 4.6, so lots of the tutorials I've checked are not very useful, because they are made with older versions of xcode. please help me, Thank you in advance!
in you AppDelegate replace this line
TableViewController *tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
with this
TableViewController *tableView = [[TableViewController alloc] initWithStyle:UITableViewStylePlain];
You're not creating an instance of TableViewController but instead UITableViewController so thus you're not getting any of your code executed. (You should have a compiler warning for this in your app delegate - make sure to heed those warnings). Likewise you're not loading the NavigationView nib anywhere - you're creating a navigation controller with the table as the root view controller. It's not clear what your objective for NavigationView is so I can't provide a recommendation for how to proceed. However, for the table view, change the following line in your app delegate
TableViewController *tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
to
TableViewController *tableView = [[TableViewController alloc] init];
In your table view xib, make sure File's Owner's class is set to be of class TableViewController (not UITableViewController). Right click on the table view and drag the circles next to 'data source' and 'delegate' to file's owner. Then right click file's owner and make sure the circle next to 'view' is connected to the table view. Save, clean, and run.
You might also find it very useful to checkout the free Sensible TableView framework. The framework will take your array and automatically generate all the table view cells, while managing all the details required to correctly setup the navigation controller. Hope this helps.
My app currently has a UINavigationController and I'd like to push a UITabBarController at some point when a button is clicked. I am trying to create it on Interface Builder (as opposed to programatically).
All online tutorials show how to create a tab bar based app, which involves dragging a UITabBarController into the MainWindow.xib which is obviously not what I want.
What I did was create a UIViewController, and its nib file, dragged a UITabBarController. Now pushing that UIViewController to the navigation controller will show an empty view (its empty view). Removing the view in the view controller will crash the app. How can I tell the UIViewController to load a UITabBarController instead of its own view?
For those down-voting me: it would be decent to at least provide a comment. The question is not a poor question. The questions is asking for suggestions for how to use a UITabBarController in an unorthodox way. I tried most of the suggestions and they do not work. If you are down-voting, at least write a comment.
You can see this this may help you
Since this is how you want your app to be: - Navigation Controller - Root View Controller - Other View Controllers - Tab Bar Controller - First VC under tab - Second VC under tab - Third VC under tab - more view controllers
in your view controller where you want to pushViewController to UITabBarController use this
//create a UITabBarController object
UITabBarController *tabBarController=[[UITabBarController alloc]init];
//FirstViewController and SecondViewController are the view controllers you want on your UITabBarController (Number of view controllers can be according to your need)
FirstViewController *firstViewController=[[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondViewController=[[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
//adding view controllers to your tabBarController bundling them in an array
tabBarController.viewControllers=[NSArray arrayWithObjects:firstViewController,secondViewController, nil];
//navigating to the UITabBarController that you created
[self.navigationController pushViewController:tabBarController animated:YES];
This tutorial might help. It comes with an example code.
Hi just make both nav controller and tabBar Controller in app delegate.
Initially add navController to your root view..
[self.window addSubview:navigationController.view];
and whenever you want to add tab bar then remove navController and add tabBarController.
-(void)addTabBarController
{
AppDelegate *appdelegte =(AppDelegate*)[[UIApplication sharedApplication]delegate];
[[[appdelegte navigationController] view]removeFromSuperview];
[[appdelegte window]addSubview:[[appdelegte tabcontroller]view]];
[[appdelegte tabcontroller]setSelectedIndex:0];
}
If you get any problem then ask me again..
In YourView controller make IBOutlet of tabBarController
in .h file
#import <UIKit/UIKit.h>
#interface YourView : UIViewController
{
IBOutlet UITabBarController *tabBarController;
}
-(IBAction)loadTabBar:(id)sender;
#end
and in .m file
#import "YourView.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation YourView
-(IBAction)loadTabBar:(id)sender
{
FirstViewController *firstView = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondView = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:firstView, secondView, nil];
[self.navigationController pushViewController:tabBarController animated:YES];
}
#end
The tabBarController IBOutlet must be connected to the UITabBarController that on the .xib file. And that UITabBarController with two view controllers named FirstViewController, SecondViewController.
I remember doing something similar to this...
I had to create a custom UITableViewController to do this, if you are going to use UINavigationController to 'push' to it.
Doing it only in interface builder may be a bit tricky, it's been a while since I've been at it, I do recall it was a bit of a nightmare to get going correctly.
The problem was, as I believe I've mentioned somewhere, is that the XIB does not have a UIView connected to it. When the UIView is deleted in a XIB file and a UITabBarController is added, the view property of the XIB has to be connected to the UITabBarController's view. I connected it and it worked. That was the reason why I was getting a SIGTRAP.
take a uiview of tab bar controller means create an interface builder with tabs and add that tab bar uivew in your classes where ever u wanted the tab bar
for example take a tab bar uiview of 3 tabs in that uiview take the three buttons in the interface builder
for every navigation of that classu should add this uiview class
-(IBAction)firt_button_pressed:(id)sender
{
}
-(IBAction)second_button_pressed:(id)sender
{
}
I'd just like to clear something up..
I have an app where the Main Window UI has a Tab bar with 3 tabs (opt1, opt2, op3). Each opt has its own xib file where i've drawn their own interfaces.
In my app delegate class I have included a UITabBar *rootController, and hooked this up to my tab bar in my Main Window xib file.
Now.. In the Tab bar, I have dragged in 3 navigation controllers (1 for each opt) and inside each one I have a 1) tab bar icon, 2) navigation bar and 3) view controller.
Back in my app delegate.h class I have included code for UINavigationController *nav1, nav2, nav3..and hooked these up accordingly in IB in MainWindow.xib (TabBar->navController1, navController2, navController3).
Is this the right way to do it? Also how can I make use of these nab bars in my opt1, opt2, opt3 class files?
here is my code:
app delegate.h
#import <UIKit/UIKit.h>
#class LoginViewController;
#interface myAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *navigationController1, *navigationController2, *navigationController3;
IBOutlet UITabBarController *rootController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController1, *navigationController2, *navigationController3;
#property (nonatomic, retain) IBOutlet UITabBarController *rootController;
#end
appdelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[rootController view]];
[window makeKeyAndVisible];
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil];
[self.rootController presentModalViewController:loginViewController animated:NO];
}
Then in my LoginController.m class , when the user enters correct credentials I call
[self dismissModalViewControllerAnimated:YES];
In my MainWindow.xib, I hook up my rootController to a TabBarController. In the TabBarController I have put 3 NavigationControllers inside it and linked them to 3 tabOption classes which each have their own .xib view.
The tab bar switches between the 3 option views nicely. However in 1 .xib view I have a button to open a new .xib. So in my tabOption1 class I have the following:
-(IBAction)openBook:(id)sender{
UIViewController *nextVC = [[PageViewController alloc] initWithNibName:#"PageView" bundle:nil];
[self.navigationController pushViewController:nextVC animated:YES];
}
However this does not open up my PageView.xib... I have connected it to my PageViewController class and everything too..and the button works because I've tested it with a UIDialog
Have you seen the Apple Programming Guides? They might give you a better understanding of how everything ties together - you could start here:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/NavigationControllers/NavigationControllers.html#//apple_ref/doc/uid/TP40007457-CH103-SW1
In answer to your question, that looks like an OK way of setting up. I really would recommend reading up a bit though :)
In response to your comment, that looks like a reasonable way to do what you're trying to achieve. If it works, then it works.
In response to your other issue then you can get the navigation controller object by doing this: self.navigationController
So you can "go to" a new view controller like this:
// make the view controller
UIViewController *nextVC = [[MyCustomViewController alloc] initWithNibName:#"MyCustomViewController" bundle:nil];
// push it onto the navigation stack
[self.navigationController pushViewController:nextVC animated:YES];
To add this to the click event on a button you need to create the button in interface builder and create an IBAction in your code. The IBAction might look like this:
- (IBAction)pushNextViewController:(id)sender {
UIViewController *nextVC = [[MyCustomViewController alloc] initWithNibName:#"MyCustomViewController" bundle:nil];
[self.navigationController pushViewController:nextVC animated:YES];
}
Then you need to link to it from interface builder. I'm not sure how to do this, I generally don't use interface builder, and certainly haven't used it since about XCode 3.
To do it programatically you can use this method:
[MyButton addTarget:self selector:#selector(pushNextViewController:) forControlEvents:UIControlEventTouchUpInside]; // always use touch up inside
Keywords to look up to help you find tutorials and stuff on the internet: ibaction uinavigationcontroller pushviewcontroller:animated: popviewcontrolleranimated:
I am trying to understand what is a proper structure of the objects when using uinavigationcontroller with a tab bar.
I want my app to have the following structure: welcome/login screen -> 3 bar tabs.
I have the following objects/classes:
AppDelegate
WelcomeViewController
TabController
FirstTab
SecondTab
ThirdTab
I have also created a uinavcontroller under WelcomeViewController once the user clicks on "enter" to the app:
-(IBAction)aMethod:(id)sender {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FirstView *controller = [[FirstView alloc] initWithNibName:#"FirstView" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
self.window.rootViewController = self.navigationController;
navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navigationController animated:YES];
}
My question is - how should I manage the tab bar - where should I declare each one of its pieces, and will I need to create a uitabbarcontroller in this case (in which case, where?)).
I am very confused as to how to place the different tab bar related declarations and none of the examples/ tutorials our there were able to clarify this for me.
BTW - I started this app from a view based application.
Thanks!
You can either set this up in code or you can do it using interface builder.
I prefer the interface builder method as you can visually see the structure of your view controllers.
This is how I do it...
In your AppDelegate.h add a property
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
In your AppDelegate.m firstly synthesize the property
#synthesize tabBarController = _tabBarController;
Set up the application:didFinishLaunchingWithOptions: method to look something like this (you may do more work in this method)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window addSubview:self.tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
In MainWindow.xib drag a Tab Bar Controller object onto your objects area (this is where your AppDelegate and Window objects are).
Ctrl + Drag from the AppDelegate to the Tab Bar Controller object and select the property that we just made.
NOTE: Now we have a Tab Bar Controller set up and ready to roll.
There should be two tabs set up as an example. If you just want to use sub classes of UIViewController then just change the classes of these objects to represent your UIViewController sub classes.
If you want to use UINavigationController then drag a UINavigationController object onto your Tab Bar Controller object.
Now click the disclosure triangle on UINavigationController and change the class of its ViewController to be your custom subclass of UIViewController.
Hey everyone, I am new to iPhone development and I'm not understanding the whole UINavigationController and UITabBarController idea. Is one a substitute for the other - how do apps such as Tweetie combine both?
I'd like to have my app have a persistent Tab Bar # the bottom (which seems to be working), but also a Navigation bar at the top which can push/pop views onto the screen without removing the tab bar.
How can I accomplish this?
What should the hierarchy look like in IB as far as my MainWindow.xib with regards to all of these controllers?
What is best practice here?
Thanks very much,
Just wrap the view controller inside the UINavigationController and Place the UINavigationController inside the UITabBar.
This will work fine for you…
Example:
NSMutableArray *tabBarViewControllers = [[NSMutableArray alloc] initWithCapacity:2];
tabBarController = [[UITabBarController alloc] init];
[tabBarController setDelegate:self];
UINavigationController *navigationController = nil;
navigationController = [[UINavigationController alloc] initWithRootViewController:<Your View controller1>];
[tabBarViewControllers addObject:navigationController];
[navigationController release];
navigationController = nil;
navigationController = [[UINavigationController alloc] initWithRootViewController:<Your View controller2>];
[tabBarViewControllers addObject:navigationController];
[navigationController release];
navigationController = nil;
tabBarController = tabBarViewControllers;
[tabBarViewControllers release];
tabBarViewControllers = nil;
Use the wizard for a Tab Bar Application, and set it up as normal. In any tab where you want to add a navigation controller, create it in the XIB using the library. My XIB has:
- File's Owner DescriptiveNameNavViewController
- First Responder
- View UIVIew
- Navigation Controller UINavigationController
- Navigation Bar UINavigationBar
Note that there isn't anything in the view. See viewDidLoad below for where the UINavigationController gets attached to the UIView.
In the header file for the Tab's ViewController (which I've here called DescriptiveNameNavViewController -- there isn't a particular standard for this, but I use [Something]NavViewController to remind me that this ViewController contains a navigation controller with the navigation stack. This is the controller name that I set in the MainWindow.xib that the wizard generates) Set up a UINavigationController * IBOutlet that has the navigation controller in the XIB attached to it:
#interface DescriptiveNameNavViewController : UIViewController {
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#end
In the controller for the DescriptiveNameNavViewController , do something like this:
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview:[navigationController view]];
DescriptiveNameController *aController = [[[DescriptiveNameController alloc ] initWithNibName:#"DescriptiveNameController" bundle:nil ] autorelease];
aController.title = #"Descriptive Title";
//
// app stuff goes here.
//
[self.navigationController pushViewController:aController animated:YES];
[self.navigationController setDelegate:self];
}
Setting the delegate in the DescriptiveNameNavViewController is super-important, because otherwise you won't get the methods called that you expect in DescriptiveNameViewController instances and anything else you push into the navigation controller's stack.
In DescriptiveNameNavViewController, implement the UINavigationControllerDelegate methods like this:
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([viewController respondsToSelector:#selector(viewDidAppear:)]) {
[viewController viewDidAppear:animated];
}
}
And that will cause messages to get propagated to controllers inside the UINavigationController like you expect. It seems like many problems that people encounter are because the viewDidAppear: or other methods aren't getting called on the ViewControllers pushed into the NavigationController.
Anyway, let me know if more detail would help.