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.
Related
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;
}
I'm having an LoginViewController which is the RootViewController. This ViewController should not have the TabBar included. The Rest of the ViewController should contain the UITabBar, But it is not showing. If i make the tabBar the rootController it will show the tabBar in the viewcontrollers. This would also make the firsttab the rootviewcontroller which it should not.
My question is then how can i make the loginview the rootViewController without an tabBar and still show the tabBar in the other viewcontrollers?
My code:
tabBarController = [[UITabBarController alloc] init];
MenuViewController *firstTab = [[MenuViewController alloc] initWithNibName:#"MenuViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:firstTab];
FixtureViewController *secondTab = [[FixtureViewController alloc] initWithNibName:#"FixtureViewController" bundle:nil];
UINavigationController *navController2 = [[UINavigationController alloc] initWithRootViewController:secondTab];
WorldCupViewController *thirdTab = [[WorldCupViewController alloc] initWithNibName:#"WorldCupViewController" bundle:nil];
UINavigationController *navController3 = [[UINavigationController alloc] initWithRootViewController:thirdTab];
LoginViewController *loginView = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
UINavigationController *navController4 = [[UINavigationController alloc] initWithRootViewController:loginView];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[navController, navController2, navController3];
navController.tabBarItem.image = [UIImage imageNamed:#"message-7"];
navController2.tabBarItem.image = [UIImage imageNamed:#"football-32"];
navController3.tabBarItem.image = [UIImage imageNamed:#"trophy-32"];
[[UITabBar appearance] setTintColor:[UIColor colorWithRed:110/255.0f green:89/255.0f blue:196/255.0f alpha:1.0f]];
[self.window setRootViewController:navController4];
[self.window makeKeyAndVisible];
What you need to do is transition the application from the LoginViewController to the Tabbar. What I would suggest doing is replacing the LoginViewController with the TabBar as the rootViewController.
Here is some sample code, perform this action in your AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LoginViewController *loginView = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
UINavigationController *navController4 = [[UINavigationController alloc] initWithRootViewController:loginView];
[self.window setRootViewController:navController4];
[self.window makeKeyAndVisible];
return YES;
}
-(void)transitionToTabBar
{
// Set the TabBar how you are in your sample code, this is just an example.
[self.window setRootViewController:[[UITabBarController alloc] initWithNibName:#"SomeNib" bundle:Nil]];
[UIView transitionWithView:self.window duration:0.5f options:UIViewAnimationOptionTransitionCurlDown animations:^{
[self.window makeKeyAndVisible];
} completion:nil];
}
You should use main View controller (for MenuViewController) and by using segue you can present another view controller which has TabBar in it.
I have tried to add a navigation controller to a tab bar controller but the tab appear black.
My code:
AppDelegate.m
#import "SettingsNavigationControllerViewController.h"
#import "SettingsViewController.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1, *viewController2, *viewController3;
SettingsNavigationControllerViewController *viewController4;
UINavigationController *navigationController = [UINavigationController alloc];
viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController3 = [[ShareViewController alloc] initWithNibName:#"ShareViewController" bundle:nil];
SettingsViewController *settingViewController = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
viewController4 = [[SettingsNavigationControllerViewController alloc] initWithRootViewController:settingViewController];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2, viewController3, navigationController];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
thank you in advance
This is because you added a navigationcontroller with no RootViewController and even doesnt initialized. Thats why the view appears as black. May be you mean to add viewController4 instead of navigationController . So change your code as below
self.tabBarController.viewControllers = #[viewController1, viewController2, viewController3, viewController4];
You need to first create the navigation controllers with rootviewcontrollers
viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *navigationController2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
Then instantiate the Tab Bar controller like this
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController1, navigationController2, nil];
Create Navigation Controllers first.
UINavigationController *nav1 = [[UINavigationController alloc] init];
UIViewController *viewController1 = [[[FirstSteps alloc] initWithNibName:#"FirstView" bundle:nil] autorelease];
nav1.viewControllers = [NSArray arrayWithObjects:viewController1, nil];
UINavigationController *nav2 = [[UINavigationController alloc] init];
UIViewController *viewController2 = [[[Profiles alloc] initWithNibName:#"SecondView" bundle:nil] autorelease];
nav2.viewControllers = [NSArray arrayWithObjects:viewController2, nil];
Then initialize your tabbar controller like this.
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav1,nav2 ,nil];
self.window.rootViewController=self.tabBarController;
Hope this helps you.
Hey mate please visit the below link for tab bar example.
I think this is good and nice example which would be helpful to you.
https://github.com/alikaragoz/AKTabBarController
You only have to set your controllers name in appDelegate.m file
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)
Im implementing a combined tab bar and navigation programatically, using the apple documentation,
it is not working when calling the initWithFrame,[goes black screen]; but if left as below code it works for showing main screen, with out the tab bar, and when using the tab bar goes black screen
here the code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSDictionary *)launchOptions {
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
StartViewController *startViewControllerView = [[[StartViewController alloc] init] autorelease]; //ojo recomendado por apple!!!
VideosViewController* VideosViewController_ = [[[VideosViewController alloc] init] autorelease];
PhotosViewController* PhotosViewController_ = [[[PhotosViewController alloc] init] autorelease];
SocialViewController* SocialViewController_ = [[[SocialViewController alloc] init] autorelease];
self.pagesNavigation = [[[UINavigationController alloc] initWithRootViewController:startViewControllerView] autorelease];
self.pagesNavigation.navigationBarHidden = NO;
NSArray* controllers = [NSArray arrayWithObjects:VideosViewController_, PhotosViewController_, SocialViewController_, startViewControllerView, nil];
self.tabBarController.viewControllers = controllers;
[self.window addSubview:startViewControllerView.view];
//self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[self.window makeKeyAndVisible];
return YES;
}
so if left as shown above, it works but if I comment the addSubview and uncomment the initWithFrame, it doesnt work,,
//[self.window addSubview:startViewControllerView.view];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
So, what Im i missing?,
what would be the right way to call the initWithFrame?
thanks a lot!
Why are all your viewcontrollers auto released? You should probably be retaining them and releasing them only when you're done with them.
As for your structure, I've found that building a single navigation controller for each tab in the tabbarcontroller, adding those to the controller, then adding the tabbarcontroller to the window works like this...
AppDelegate.h
property (nonatomic, retain) UITabBarController *tabBarController;
property (nonatomic, retain) UINavigationController *firstNavController;
property (nonatomic, retain) UINavigationController *secondNavController;
property (nonatomic, retain) FirstViewController *firstViewController;
property (nonatomic, retain) SecondViewController *secondViewController;
AppDelegate.m
firstViewController = [[FirstViewController alloc] someInitMethod:someArg];
firstNavController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
secondViewController = [[SecondViewController alloc] someInitMethod:someArg];
secondNavController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
tabBarController = [[UITabbarController alloc] init];
NSArray *tabs = [NSArray arrayWithObjects:firstNavController, secondNavController, nil];
[tabBarController setViewControllers:tabs animated:NO];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];