Combining UINavigationController with UITabBarController - ios

I'm developing an iOS app which asks the user to either login or signup before using the functionality. The flow is;
The app displays a screen with 2 buttons 1) Login 2) Signup
Upon clicking either button the app navigates the user to different view controllers using UiNavigationController.
Upon successful login the user is directed towards a home view controller which displays a tab bar on the bottom of the view and a UiNavigationController's top bar on the top of the view.
To implement this, I have set the UINavigationViewController as the root view controller in the AppDelegate file.
As soon as the user is authenticated, I push the tab bar controller on the UiNavigationController using the following code.
FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
[firstViewController setTabBarItem:[[UITabBarItem alloc] initWithTitle:#"1st" image:[UIImage imageNamed:#"1st.png"] tag:101]];
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[secondViewController setTabBarItem:[[UITabBarItem alloc] initWithTitle:#"2nd" image:[UIImage imageNamed:#"2nd.png"] tag:102]];
ThirdViewController *thirdViewController = [[ThirdViewController alloc]initWithNibName:#"ThirdViewController" bundle:nil];
[thirdViewController setTabBarItem:[[UITabBarItem alloc] initWithTitle:#"3rd" image:[UIImage imageNamed:#"3rd.png"] tag:104]];
UITabBarController *tabController = [[UITabBarController alloc] init];
[tabController setViewControllers:[NSArray arrayWithObjects:firstViewController, secondViewController,thirdViewController, nil]];
[self.navigationController pushViewController:tabController animated:YES];
Is this the right approach?
Someone just said that the using tab bar controller as root view controller will be a better approach.
How can I just set the tab bar controller as root view controller as I dont want to show the tab bar on login/signup screens....
Thankyou!

Just create a protocol, so you can communicate between your login UIViewController and your AppDelegate. Once the login has been done, you can change the rootViewController. You can also get a reference to the AppDelegate, by doing something like:
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Although I prefer to use protocols to communicate between different objects.

Related

tab bar not displayed when added to navigation controller IOS

I have a navigation controller which has view controller(VC1) . This view controller has 3 button out of which 1 directs to a tab bar controller. From tab1 of the tab bar controller a button is there which navigates to a View controller(vc2).
The problem is VC2 is not displaying the tab bar. How can I make my VC2 display the tab bar.
Navigation Controller—> View Controller-->Tab bar Controller —>Tab1 -> View Controller (does not show tab bar)
I am doing this in IOS
Using a tabbarcontroller within a navigation controller is not recommended by Apple. However it is possible to do so.
In the VC1, write the following code.
UITabBarController *tabBarController = [[UITabBarController alloc] init];
MyStartViewController *startController = [[MyStartViewController alloc] initWithNibName:#"MyStartViewController" bundle:Nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:startController];
SecondViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.viewControllers = #[navController, viewController2];
[self.navigationController pushViewController:tabBarController animated:YES];
Now within startController, add a UIButton. And in the button action, push the new VC2 from it.
Button action:
- (IBAction)buttonPressed {
MyViewController2 *vc2 = [[MyViewController2 alloc] initWithNibName:#"MyViewController2" bundle:nil];
[self.navigationController pushViewController:vc2 animated:YES];
}
Hope this will serve your purpose.

How to display navigation controller (set of view controllers) such as login or register before adding UITabBarController

I had an application in which I need to have a login or register system before the tab bar controller is added to the window, such as in Instagram.
I have added 5 navigation controllers (with view controller as its root) to the UITabBarController and then set it as the root of the window. Before that, I need to have another UINavigationController for the login system.
If I add that, how do I remove it before adding tab?
Another problem is that I also have to handle logging out, so I need to come back to it.
Can anybody help me with me how to do this?
I suggest to you loading Loginview From Delegate window as we did Normally. and from Logged Success its button click you set TabbarController like this:-
UIViewController *viewControllerPostalCode2 = [[cntrServices alloc] initWithNibName:#"cntrServices" bundle:nil];
UIViewController *viewControllerPostalCode3 = [[cntrInquiryViewController alloc] initWithNibName:#"cntrInquiryViewController" bundle:nil];
UINavigationController *navPostage1 = [[UINavigationController alloc] initWithRootViewController:viewControllerPostalCode2];
UINavigationController *navPostage2 = [[UINavigationController alloc] initWithRootViewController:viewControllerPostalCode3];
//
navPostage1.navigationBar.tintColor =DARK_BACKGROUNDNavigation;
navPostage2.navigationBar.tintColor =DARK_BACKGROUNDNavigation;
//
self.tabBarForServicesController = [[UITabBarController alloc] init];
self.tabBarForServicesController.delegate=self;
self.tabBarForServicesController.viewControllers = [NSArray arrayWithObjects:navPostage1,navPostage2,nil];
[self.navigationController pushViewController:self.tabBarForServicesController animated:YES];
I Done this type of Task using this method and at the Logged Out just poptoRootviewController work back to the Logged in Screen.
I have done this like adding my tabbarcontroller as rootViewController to UIWindow and in applicationbecomeactive delegate i present a controller with navigation controller like when required and simply dismiss the controller when authentication done
UIViewController *topViewController = [self.navController topViewController];
if (![topViewController isKindOfClass:[LGLoginViewController class]]) {
[self.navController popToRootViewControllerAnimated:YES];
self.navController = nil;
LGLoginViewController* loginView = [[LGLoginViewController alloc] initWithNibName:#"LGLoginViewController"bundle:nil];
if (!self.navController) {
self.navController = [[UINavigationController alloc] initWithRootViewController:loginView];
} else {
[self.navController initWithRootViewController:loginView];
}
self.navController.delegate = self;
[self.window.rootViewController presentModalViewController:self.navController animated:NO];
}

Dismiss TabBarController From one of it's UINavigationControllers and return to the Controller from where the TabBarController was presented

I am presenting a UITabBarController from another ViewController (HomeViewController). The TabBarController in turn contains UINavigationControllers. However, when from one of the navigation controllers, the user presses the home button, he is required to go to the original ViewController from where the TabBarController was presented.
**tabBarController is not the rootViewController of my window.
Here's my code.
In AppDelegate, I am creating and configuring my TabBarController.
self.custCareVC = [[CustomerCareViewController alloc] initWithNibName:#"CustomerCareViewController_iPhone" bundle:NULL];
self.POController = [[PurchaeOrderViewController alloc] initWithNibName:#"PurchaeOrderViewController_iPhone" bundle:NULL];
self.accAndContactsController = [[AccountsAndContactsViewController alloc] initWithNibName:#"AccountsAndContactsViewController_iPhone" bundle:NULL];
self.customerCareNavController = [[UINavigationController alloc] initWithRootViewController:self.custCareVC];
self.customerCareNavController.title = #"Customer Service";
self.purchaseOrderNavController = [[UINavigationController alloc] initWithRootViewController:self.POController];
self.purchaseOrderNavController.title = #"PO";
self.accAndContactsNavController = [[UINavigationController alloc] initWithRootViewController:self.accAndContactsController];
self.accAndContactsNavController.title = #"Accounts And Contacts";
self.tabBarController = [[UITabBarController alloc] init];
//self.tabBarController.tabBar.backgroundImage = [UIImage imageNamed:#"bluehead.png"];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:self.customerCareNavController, self.accAndContactsNavController, self.purchaseOrderNavController, nil];
In my HomePageViewController, i am presenting it in the following way (on click of a button):
AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
appDel.tabBarController.delegate = self;
[self presentViewController:appDel.tabBarController animated:YES completion:NULL];
Now i need to dismiss my tabBarController after a user presses a Button on any of the navigation controllers (present in the tabBarController) and show the HomeViewController again..!!
You need to create a function in your target controller (which has the power to dismiss the tabBarController) and call that function from your topmost(current) controller/ controller the user is currently interacting with. To achieve the above, you need to first get the tabBarController object from the current controller using parent view controller. Then get the parent view/ root view controller of that controller and performSelector (function) which you created in the first controller.
Be sure to check doesRespondToSelector before you call performSelectorso as to avoid any nasty crashes.
Another way, though pretty hackie is to store a weak reference of the first controller in the AppDelegate and access the same from you current controller.

Push ViewController on Top of TabBarController

I'm stuck on a problem I really don't know how to solve:
I have a TabBarController defined in my AppDelegate.
UITabBarController *tabBarController = [[UITabBarController alloc] init];
In this TabBarController i have several other NavigationControllers which have UiVieController inside:
ProgramController *programContr = [[ProgrammController alloc] init];
UINavigationController navControllerPro = [[UINavigationController alloc] initWithRootViewController:programContr];
ManualController *manualContr = [[ManualController alloc] init];
UINavigationController navControllerMan = [[UINavigationController alloc] initWithRootViewController:manualContr];
and i add the NavigationController to the TabBarController:
tabBarController.viewControllers = [NSArray arrayWithObjects:navControllerPro,navControllerMan, nil];
I set the tabBarController to the rootViewController:
self.window.rootViewController = tabBarController;
[[self window] makeKeyAndVisible];
That works fine.
Now i want to add a "Login Screen" on top of that.
I did this with:
[tabBarController presentModalViewController:navControllerLogin animated:YES];
Now the TabBarController loads its content in the background even if the LoginViewController is in front. How to load the TabBarController only if a Button is pressed on the LoginViewController?
Please help me.
The tab bar controller is loaded everytime beacuse you set it as the rootViewController.
You should set a normal viewController as the root.. and if the login was succesfull the you should call the tabBarController to be loaded.
In other words, in the appDelegate there should be only the login window.. and in the loginViewController, if the login was ok, you should call and load your tabBarController with all its controller.. using storyboard makes it a lot easier.

how to add uinavigationcontroller as a second view not as rootviewcontroller

i know how to add uinavigationcontroller as root view and also how to push view in uinavigationcontroller.
What i am confused in the first view which is a root view is a simple view with button when this button is tapped it will show second view.
I want this second view as uinavigationview.
any ideas how to do it, i tried to search for the solution but didn't get any nor any similar question is asked before.
basically i am trying to work without interface builder to learn things in depth.
assuming you are presenting the 2nd view controller modally
instead of
UIViewController *vc = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:vc animated:YES];
do:
UIViewController *vc = [[[UIViewController alloc] init] autorelease];
UINavigationController *nc = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
[self presentModalViewController:nc animated:YES];

Resources