TabBar and Navigation Controller - ios

Hi I am new to iOS and I am trying to display a Navigation Controller in a TabBar based app.
Here is is what I got:
H file:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UITabBarController *tabBarController;
#property (strong, nonatomic) UINavigationController *navigationController;
#end
M file:
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UIViewController *viewController3 = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
UIViewController *viewController4 = [[FourthViewController alloc] initWithNibName:#"FourthViewController" bundle:nil];
UIViewController *viewController5 = [[FifthViewController alloc] initWithNibName:#"FifthViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2,viewController3,viewController4,viewController5];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController5];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}

Instead of adding viewController5 to the tab bar controller's view controllers,, add the navigation controller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UIViewController *viewController3 = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
UIViewController *viewController4 = [[FourthViewController alloc] initWithNibName:#"FourthViewController" bundle:nil];
UIViewController *viewController5 = [[FifthViewController alloc] initWithNibName:#"FifthViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController5];
self.tabBarController.viewControllers = #[viewController1, viewController2,viewController3,viewController4,self.navigationController];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}

This doesn't work. Mixing the view controllers with the navigation controller gives you view controllers without nav and a nav controller without a view controller. You need a nav controller for each vc and then create an array of those nav controllers.
Here is an answer that works: How to add UITabBarController programmatically (no xib file or storyboard)

Related

NavigatorController is nil

AppDelegate.m
_viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:_viewController];
nav.navigationBar.barStyle = UIBarStyleBlackOpaque;
[_window addSubview:nav.view];
ViewContoller.m
UINavigationController *nav = self.navController;
[nav pushViewController:controller animated:YES];
I don't know why the UINavigationController always nil.
Please help!!
Instead of adding navigationController's view as window's subview try adding navigationController as window's rootViewController
window.rootViewController = nav;
[_window makeKeyAndVisible];
homeViewController = (mainStoryboard.instantiateViewControllerWithIdentifier("register") as? RegisterViewController)!
let navigationController :UINavigationController = UINavigationController()
navigationController.pushViewController(homeViewController, animated: true)
navigationController.navigationBarHidden = false
window?.rootViewController = nil
window?.rootViewController = navigationController
window?.makeKeyWindow()
#interface AppDelegate ()
#property (strong, nonatomic) UINavigationController *navigationController;
#end
//In Your Appdelegate didfinishlaunching method:
self.window = [[UIWindow alloc] init];
[self.window makeKeyAndVisible];
self.navigationController = [[UINavigationController alloc] initWithRootViewController: YourViewController];
self.window.rootViewController = self.navigationController;
//In Your View controller:
[self.navigationController pushViewController:controller animated:YES];
NEW SOLUTION
try this
in AppDelegate.m
#implementation AppDelegate
{}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *_navController = [[UINavigationController alloc] init];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = _navController;
ViewController* _viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[_navController pushViewController:_viewController animated:YES];
return YES;
}
in ViewContoller.m now this will work:
UINavigationController *nav = self.navigationController;
[nav pushViewController:controller animated:YES];
OLD SOLUTION
try this code
in AppDelegate.h be sure to have this at least
#interface AppDelegate : NSObject <UIApplicationDelegate>
{}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#end
in AppDelegate.m at least this
#implementation AppDelegate
{}
#synthesize window=_window;
#synthesize navController=_navController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *_navController = self.window.rootViewController;
UIViewController* _viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[_navController pushViewController:_viewController animated:YES];
return YES;
}
#end
in storyboard be sure to have created a NavigationController binded to a ViewController, defined as initial view controller and binded as root view controller for the binded view controller
in the app general settings tab be sure to have set the storyboard in the deployment info section (also in this section you could set status bar style)
in ViewContoller.m now this will work:
UINavigationController *nav = self.navigationController;
[nav pushViewController:controller animated:YES];
to edit the navigationBar style you can do it this way
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
}

How to programmatically add a UITabBarController & UINavigationController in AppDelegate?

How to add a UINavigationController & UITabBarController programmatically in app delegate.
Don't forget in the AppDelegate.h file to add:
#property (strong, nonatomic) UITabBarController *tabBarController;
Below is the AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.tabBarController = [[UITabBarController alloc] init];
ViewController1 *VC1 = [[ViewController1 alloc] init];
VC1.title = #"Tab Title Here";
UINavigationController *VC1Navigation = [[UINavigationController alloc]
initWithRootViewController:VC1];
ViewController2 *VC2 = [[ViewController2 alloc] init];
VC2.title = #"Tab Title Here";
UINavigationController *VC2Navigation = [[UINavigationController alloc]
initWithRootViewController:VC2];
ViewController3 *VC3 = [[ViewController3 alloc] init];
homeView.title = #"Tab Title Here";
UINavigationController* VC3Navigation = [[UINavigationController alloc]
initWithRootViewController:VC3];
NSArray* controllers = [NSArray arrayWithObjects:VC1Navigation, VC2Navigation, VC3Navigation, nil];
self.tabBarController.viewControllers = controllers;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}

facebook login with tabBarController

I am trying to add a Facebook Login function on my app. However, somehow it gives an error saying "'UIViewControllerHierarchyInconsistency', reason: 'adding a root view controller as a child of view controller:'
".
My app delegate is written as follow. Could anyone give me an advice how I could fix the problem?
AppDelegate.h
#property (strong, nonatomic) UITabBarController *tabBarController;
#property (strong, nonatomic) UINavigationController *navigationController;
#property (strong, nonatomic) LoginViewController* loginViewController;
#property (strong, nonatomic) FirstViewController *mainViewController;
AppDelegate.m
self.loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginViewController"
bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.loginViewController];
self.navigationController.delegate = self;
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
//mainwindow
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// ViewControllers array
NSMutableArray *viewControllers = [[NSMutableArray alloc] init];
[self resetMainViewController];
//homeview
self.mainViewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
//adding navigation controller
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.mainViewController];
[viewControllers addObject:self.navigationController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
//secondview
SecondViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
//adding navigation
UINavigationController *navController2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[viewControllers addObject:navController2];
// Thirdview
ThirdViewController *viewController3 = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
//adding navigationcontroller
UINavigationController *navController3 = [[UINavigationController alloc] initWithRootViewController:viewController3];
[viewControllers addObject:navController3];
//fourthview
FourthViewController *viewController4 = [[FourthViewController alloc] initWithNibName:#"FourthViewController" bundle:nil];
//adding navigation controller
UINavigationController *navController4 = [[UINavigationController alloc] initWithRootViewController:viewController4];
[viewControllers addObject:navController4];
//fifthviewcontroller
FifthViewController *viewController5 = [[FifthViewController alloc] initWithNibName:#"FifthViewController" bundle:nil];
//adding navigation controller
UINavigationController *navController5 = [[UINavigationController alloc] initWithRootViewController:viewController5];
[viewControllers addObject:navController5];
//tabbarcontroller
self.tabBarController = [[UITabBarController alloc] init];
[self.tabBarController setViewControllers:viewControllers];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
Thank you.
You set self.navigationController to self.window.rootViewController at the beginning, then add it to the viewcontrollers of the self.tabBarController, this is the problem. You should remove all other self.window.rootViewController assignments, and remain the last one.

TabBar application with NavigationBar

I'm building an App which is TabBar based. One of the tabs will display a TableView and I would like to have a NavigationBar at the top.
However I need to localize everything in this app to several languages so it needs to be done in code.
I have the tab bar set up in the AppDelegate;
#implementation AppDelegate
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[HomeViewController alloc] initWithNibName:#"HomeView" bundle:nil];
UIViewController *viewController2 = [[RecycleViewController alloc] initWithNibName:#"RecycleView" bundle:nil];
UIViewController *viewController3 = [[SettingsViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
UIViewController *viewController4 = [[SettingsViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2,viewController3, viewController4, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Each of the windows has the code for the information on the tab.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Home", #"Home");
self.tabBarItem.image = [UIImage imageNamed:#"home"];
}
return self;
}
So far so good, but the RecyclingView (TableView) need a navigation bar where I can set the title using NSLocalizedString.
I would be really grateful for some help.
you need to add a UINavigationController at the second index of your tabBarController's viewControllers instead of adding a view controller -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[HomeViewController alloc] initWithNibName:#"HomeView" bundle:nil];
UIViewController *viewController2 = [[RecycleViewController alloc] initWithNibName:#"RecycleView" bundle:nil];
UIViewController *viewController3 = [[SettingsViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
UIViewController *viewController4 = [[SettingsViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, navController,viewController3, viewController4, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
to set the title at navigation bar you can write this in your RecycleViewController's viewDidLoad
[self.navigationItem setTitle:#"title"];
You can localize the xibs with Interface Builder so you shouldn't have to do it programatically.
http://www.icanlocalize.com/site/tutorials/iphone-applications-localization-guide/
The answer for xcode 4.3.2 is:
alloc the UINavigationBar in RecycleViewController.m as this:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self];
self.view addSubview:navController.view;
But there is a bug, that navigation bar will display a blank at the top, about 10pixels.
So here is another solution:
use xib builder, add a navigation bar from libary in the top of view RecycleViewController.xib, press ctrl+"navigation Item", point to RecycleViewController.h to insert an IBOutlet,then you will have a good looking navigation bar to show.

How to insert UINavigationController inside UITabBarController

How to insert UINavigationController inside UITabBarController.
Currently I have main UITabBarController with declatarion inside application delegate like this (so tab is main)
self.window.rootViewController = self.tabBarController;
And inside one of tabs I want to insert UINavigationController, and can't get it.
The code is contructed like this:
MainWindow.xib with UITabBarController object with tab typed as UINavigationController (point to NavigationHistory.xib) - screenshot: invalid link
NavigationHistory.xib contains only UINavigationController where view point to History.xib
History.xib have only UITableView element - screenshot: invalid link
And now UIViewController doesn't display my View1 view, and I have no clue why it may be. Maybe you have any clue? or point me to the place where such configuration is done.
I'll answer myself. It's good explained at
https://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/CombiningViewControllers.html
Write a code in appdelegate.m file.....
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSMutableArray *Mutablearray = [[NSMutableArray alloc] init];
UIViewController *1st_View = [[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:nil];
UINavigationController *Navigation = [[UINavigationController alloc] initWithRootViewController:1st_View];
[Mutablarray addObject:Navigation];
UIViewController *2nd_View = [[SecondViewController alloc] initWithNibName:#"SecondViewController_iPhone" bundle:nil];
UINavigationController *Navigation = [[UINavigationController alloc] initWithRootViewController:2nd_View];
[Mutablearray addObject:Navigation];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = Mutablearray;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Add your controller object to UINavigationController, and add that navigationcontroller object to UITabBarController
UINavigationController is a subclass of UIViewController, a UITabBarController expects an array of UIViewControllers (and therefore UINavigationController ); this tells me me that I can give a UITabBarController an array of UINavigationControllers (or sublasses thereof) giving the desired interaction.
Ref : https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITabBarController_Class/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UITabBarController *tab = [[UITabBarController alloc] init];
SimpleTableViewController *tableView = [[SimpleTableViewController alloc] init];
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:tableView];
UITabBarItem *item = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemHistory tag:0];
nav1.tabBarItem = item;
AboutViewController *about = [[AboutViewController alloc] init];
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:about];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemFeatured tag:0];
nav2.tabBarItem = item2;
tab.viewControllers = #[nav1,nav2];
self.window.rootViewController = tab;
[self.window makeKeyAndVisible];
return YES;
}

Resources