I have a login view in my application which loads the main menu view after the user enters the correct username and password. I'm using this to go to main menu view:
MenuViewController *menuViewController=[[MenuViewController alloc] initWithNibName:#"MenuViewController" bundle:nil];
menuViewController.title=#"Felton";
UINavigationController *tnavController=[[UINavigationController alloc] initWithRootViewController:menuViewController];
tnavController.view.frame=CGRectMake(0, 0, 1024, 748);
[menuViewController release];
self.navController=tnavController;
[navController release];
for(UIView *subview in self.view.subviews)
{
[subview removeFromSuperview];
}
[self.view addSubview:self.navController.view];
So my question is how exactly am I going to go back to the login page when the logout button is pressed. I've tried the same way as above but the problem I have is that each time the user presses the logout button the login page gets 1 navigation bar, and they pile on each other each time. Is there any way that I can stop this from happening? Because, my login page shouldn't have a navigation bar.
thanx in advance
Although it's not clear from your question what the exact flow through your app is, you certainly shouldn't be adding the navController view as a subview.
You'd be better placed to have the main menu as the rootViewController of your main window, and then present the login view controller on top of it (using presentModalViewController:).
Create a delegate protocol in your login view controller, and make the main menu the delegate. WHen they login, the delegate method fires, and the main menu dismisses the login view. When they log out, the main menu can present the login view again.
Related
I have a login screen as my root view controller. If the user is already logged in, I want to skip over the login screen and show the main view controller.
The code below does that, but it shows a back button in the nav bar instead of the default nav bar.
Is there a way to remove the back button? There is a menu button that is supposed to be there, so simply hiding the back button will not suffice.
Thanks!
- (void)viewDidLoad {
if(GetUserName != nil){
[self pushingView:YES];
}
[super viewDidLoad];
}
-(void)pushingView:(BOOL)animation{
MainViewController *revealViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"RevealViewController"];
[self.navigationController pushViewController:revealViewController animated:animation];
}
Don't try to remove the back button, instead remove the need for the back button. Instead of using pushViewController:animated: use setViewControllers:animated:. In this way you only have one view controller on the stack (and you save the memory of keeping the view controller in existence).
Ideally you wouldn't even load the login view controller and then you'd save even more memory and time.
In my iOS Project, there is a login ViewController that sends the user to a TabViewController if he has the right credentials.
This TabViewController has 5 tabs, the fifth one is for Logout, which send the user back to the Login ViewController, and of course clears out the already filled credentials of the user.
My problem is that i have the menu of the TableView shown in my Login page.
How to i get rid of this menu in my Login ViewController page ?
I use Xcode6 & Objective-C
if you need any further explanations/source code of my problem, feel free to ask.
note:
In the beginning, I mean when the Login ViewController is first shown to the user, the menu doesn't show.
It turns out that whole UI architecture of your app is based on the UITabBarController. However it is not very good practice in your case. I would like to suggest you add separate modal controller for presenting login page.
Try:
self.tabBar.hidden = YES;
Assuming that you are using a storybaord I have the given solution
I created a sample application and tried replicating your issue, so here's the look at my storyboard
The way i designed it i have a separate login view controller and two view controller (Menu List and Logout) which are embedded in a tabbar controller.
If you're new to storyboard then embedding viewControllers with tabbarController is pretty much straight forward, you select the view controller first and then go to the editors menu in Xcode
Alright now coming back to business, code which i added on the IBAction of the login screen button is given below where MainTabbar is the storyboardID of the TabMaster controller
AppDelegate *appdel = [UIApplication sharedApplication].delegate;
UIStoryboard *storyBoard = appdel.window.rootViewController.storyboard;
TabMasterController *tabController = [storyBoard instantiateViewControllerWithIdentifier:
#"MainTabbar"];
[appdel.window setRootViewController:tabController];
When i executed the application everything was OK and I was able to see the tabbar items after I hit the action button on login screen
Now its time to write some code for the logout tabbar item, so I selected the view controller assigned to the Main tabbar controller and added the delegate mentod of UITabbarController which looks some what like this
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
// Since i have two tabbar items 1 generally means logout in my case
if (tabBarController.selectedIndex ==1) {
AppDelegate *appdel = [UIApplication sharedApplication].delegate;
UIStoryboard *storyBoard = appdel.window.rootViewController.storyboard;
ViewController *tabController = [storyBoard instantiateViewControllerWithIdentifier:
#"LoginVC"];
[appdel.window setRootViewController:tabController];
}
}
LoginVC is the storyboardID of the Login View controller
After adding the above code when i used to tap on the logout tabbar item I was able to go back to the login screen in my storyboard.
Hope that helps.
Either you can add tab bar item programmatically or you can add in storyboard
If programmatically then add like
self.tabBarController.viewControllers = [NSArray arrayWithObjects:
[[UINavigationController alloc] initWithRootViewController:self.myContactsController],
[[UINavigationController alloc] initWithRootViewController:self.searchController],
[[UINavigationController alloc] initWithRootViewController:self.registrationController],
[[UINavigationController alloc] initWithRootViewController:self.loginController], nil];
Set tabbarController as initial view controller in storyboard
After checking login credential, On success
// to get list of current tab bar items
NSMutableArray *tbViewControllers = [NSMutableArray arrayWithArray:[self.tabBarController viewControllers]];
// to remove tab bar items using index value
[tbViewControllers removeObjectAtIndex:3];
[tbViewControllers removeObjectAtIndex:2];
// to add tab bar items
[tbViewControllers addObject:[[UINavigationController alloc] initWithRootViewController:self.myProfileController]];
[tbViewControllers addObject:[[UINavigationController alloc] initWithRootViewController:self.logoutController]];
// to set pre selected tab bar item
self.tabBarController.selectedIndex=2;
// set array items in tab bar
[self.tabBarController setViewControllers:tbViewControllers];
Fixed it, it's not the optimal solution but it worked for me:
what I did is :
1- I deleted the Tab Bar Item from my Login ViewController
2- I inserted a logout button in my table view screens
3- I added segues from my Table view screens to the login screen in my storyboard.
This way if the user clicks on the logout button , he will be directed to the login screen & cannot go back where he was unless he enters his credentials.
thanks for your time,here's my app's structure:It contains a MainController,and a LoginController, when user lanuch the app, first thing is to judge the login state,if it's yes, then set childController(aka.MainController) to RootViewController's (aka,NavigationController), else set childController(aka.LoginController) to RootViewController's (aka,NavigationController), when user input the username and password correctly,set childController(aka.MainController) to RootViewController's (aka,NavigationController)
When user click the quit button in the setting controller which belongs to MainController,then:
LoginController *vcLogin = [[LoginController alloc] init];
UINavigationController *ncRoot = [[UINavigationController alloc] initWithRootViewController:vcLogin];
[[UIApplication sharedApplication].keyWindow setRootViewController:ncRoot];
Now, the problem appears, console printed:
attempt to dismiss modal view controller whose view does not currently appear.
self = <_UIModalItemAppViewController: 0x9da0060> modalViewController =<_UIModalItemsPresentingViewController: 0x9e9bac0>
You know where the wrong-thing is?
This is not the way to set a new UIViewController. You should use presentViewController to present a modal view controller. If you want to use pushViewController without animation that's also possible. But it's a bad idea to change the rootViewController. Since that's not how the ViewController hierarchy is set up in iOS.
I'm a bit lost trying to figure it out...
I have a tab bar based app with login screen at the start. Login screen should be done as Modal View Controller BEFORE tab bar controller appears.
The problem is that I can present it only in viewDidAppear: method of TabBarController. And user can see for half a second content of the UITabBarController. I've tried to move call to viewDidLoad: or viewWillAppear: but it logs an error in console: "whose view is not in the window hierarchy!". As far as I can understand you can only add ModalViewController when all child UIViewControllers of UITabBarController are loaded, ad that happens in viewDidAppear: delegate method.
Do you have any solution how to show login screen without showing TabBarController before?
I've tried 2 ways of displaying ModalViewController, both of them work in viewDidAppear: only
XIB file with login view and using presentViewController: code
self.loginController = [[LoginViewController alloc] init];
[self presentViewController:self.loginController animated:NO completion:nil];
Storyboard, modal segue and calling it from the code:
[self performSegueWithIdentifier:#"loginScreen" sender:self];
Instead of a modal, you might consider pushing the login screen onto a navigation stack. Inside viewWillAppear: you can just instantiate your login viewController and push it. You could also do it in viewDidLoad if you'd like.
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController pushViewController:yourInstantiatedLoginViewController animated:NO];
}
I have created an application that has a Login.
It starts with a Welcome View Controller, checks if the user is logged in if not, opens a Login View Controller. If the user is logged in, or once they have it pushes the user to the Home View Controller like this.
App Delegate (did finish launching)
self.welcomeViewController = [[APPWelcomeViewController alloc] init];
self.homeViewController = [[APPHomeViewController alloc] initWithNibName:#"APPHomeViewController" bundle:nil];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.welcomeViewController];
self.navController.navigationBarHidden = YES;
self.window.rootViewController = self.navController;
Once the user is logged in it pushes the home view.
// Push the homeViewController onto the navController
[self.navController pushViewController:self.homeViewController animated:YES];
This all works fine up to this point. I then use a modal view controller for the Setting, which includes a button to Logout. The logout of the user runs this:
// Log the user out
[User logOut];
// Then we need to remove the Settings Modal View Conrtoller
[self.presentingViewController dismissModalViewControllerAnimated:YES];
// Then we need to take user back to welcomeViewController
[self.navigationController pushViewController:welcomeViewController animated:YES];
It dismisses the Settings View controller as expected, but the navigation controller remains on the Home view. There is no error, does anyone know why this is not working correctly?
Resolved by re-arranging code. Searching for current user on the appdelegate instead then either loading the nav controller with the root controller of home view or running a method to load the welcome view controller.
The welcome view controller then checks for user as well, if not current user it presents the modal login view controller
you dont need to push navigation controller, once you init your window with the navigation controller that contain the welcome view controller.
if you want to add more view inside this stack (inside welcome view controller) you call method self.navigation controller pushviewcontroller ... if you want to remove from stack, call popviewcontroller..you ll go to your main view stack (root).
Try this:
// Take me back to the root navigation view controller (APPWelcomeViewController)
[self.navigationController popToRootViewControllerAnimated:YES];