when the app is launched, i have placed a view controller(login) after validating the field it is redirected to tab bar controller. The problem is i have to place logout button and when clicking logout button it should go to the root view controller(login page). I have tried pushing from tab bar controller to root view controller, it is pushed but still facing few tab bar issues while proceeding further. How can i pop/push to root view controller from tab bar item ?
I'd imagine in your AppDelegate.m, You have created a navigation controller with the LoginUIViewController as the RootViewController.
You could solve the problem like this:
For example, you have a FirstTabUIViewController in your TabBarController, you want to go back to your LoginUIViewController (your RootViewController) from the FirstTabUIViewController.
Create a reference to your TabBarController in the FirstTabUIViewController.h and .m
#property (strong, nonatomic) IBOutlet UITabBarController *tabBarController;
#synthesize tabBarController = _tabBarController;
Create a method handles "LogOut" button click in .m
-(IBAction)logoutBtnTapped:(UIBarButtonItem *)sender{
[self.tabBarController.navigationController popToRootViewControllerAnimated:YES];
}
That it is! Hope that helps :)
May be you can use UINavigationController for root view controller http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
There are some examples about custom back buttons. If you want to use default back button you can rename as logout and give an action on it.
Just an idea.
You just need to place the login screen in appdelegate window again when you clicked the logout button.
LoginViewController *loginVC = [[LoginViewController alloc]init];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.window setRootViewController:loginVC];// This will initiate the login screen again
This works fine for me in same case,
ChooseStateViewController *loginVC = [[ChooseStateViewController alloc]initWithNibName:#"ChooseStateViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:loginVC];
[nc.navigationBar setTintColor:[UIColor blackColor]];
AppDelegate *appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate.window setRootViewController:nc];
Related
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.
Here is the scenario:
The first scene in my storyboard is a login view. It's a UIViewController. When the user is logged in, it shows the home view which is embedded in a navigation controller. I'm adding a log out functionality which should take me back to the first scene in the storyboard which is the login view. How do I do that?
Here is an image of the storyboard showing the login view -> navigation controller -> home view
This is my implementation so far. In the log out action, I clear the session, and pop to root view controller. It does not work because I am still stuck on the home view since it is the root view controller of the navigation controller. However, If I restart the app, the user is logged out and I'm left with the login view.
Code:
[self.navigationController popToRootViewControllerAnimated:NO];
// Set at beginning of storyboard
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
app.loginViewController = [mystoryboard instantiateViewControllerWithIdentifier:#"loginViewController"];
Use unwind segues for that.
In your LoginViewController, declare a method with this signature
- (IBAction)unwindToLoginViewController:(UIStoryboardSegue*)segue
Go to your HomeViewController and control drag from your logout button to the Exit button at the top of your view controller window (see screenshot below), then select the unwindToLoginViewController segue. That's it!
U can pop by using navigationController.viewControllers.Get all View Controllers among navigationController,identify it and then pop.If u have pushed the segue from LoginView to HomeView
if([self.navigationController.viewControllers[0] isKindOfClass:[LoginViewController class]])
{
[self.navigationController popToViewController:self.navigationController.viewControllers[0] animated:YES];
}
Hope it helps you...
Try this answer. First you create a navigation controller. make it "is initial View Controller". After that connect login Viewcontroller as a root view controller And connect home controller with facebook button Action.
Navigation Controller -> Login Controller -> Home Controller
Your Storyboard is look like this
After that when you logout from HomeViewController then Just add this method:
-(IBAction)logOut_Action:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
Its working Fine. Please implement like this and let me know if you face any problem. :)
Try this:
[self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
My app starts with a navigation controller which opens a UIViewController. This screen works as a login page.
On login, I open a UITabBarController like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UITabBarController *obj=[storyboard instantiateViewControllerWithIdentifier:#"MainTab"];
self.navigationController.navigationBarHidden=YES;
[self.navigationController pushViewController:obj animated:YES];
Inside my tab bar controller, I want when clicking a button to switch tab programmatically. I tried the following 3, neither of them worked. Code is place inside a method, which is invoked when the button is clicked.
For the first 2, the tab didn't change - still my initial tab is highlighted and the correct view controller is not shown. For the last one, app crashes.
1st :
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:1];
2nd :
[self.parentViewController.tabBarController setSelectedIndex:1];
3rd:
UITabBarController *MyTabController = (UITabBarController *)((AppDelegate*) [[UIApplication sharedApplication] delegate]).window.rootViewController;
[MyTabController setSelectedIndex:1];
What am I missing?
for a tabBar inside a navigation controller...What am I missing?
One thing you're missing is the order of containment that's allowed for view controllers. Specifically, you can put a navigation controller inside a tab controller, but not the other way around.
I want to know if it is possible to have a first view that acts as a menu (that has a couple of buttons for which one is Edit). I want to be able when I click on edit to then show a split view. Now, when I do that, I get the error :
Application tried to present a Split View Controllers modally
My code in the action method of the edit button is :
UIStoryboard *editorStoryboard = [UIStoryboard storyboardWithName:#"EditorStoryboard" bundle:nil];
UIViewController *editorViewController = [editorStoryboard instantiateInitialViewController];
editorViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:editorViewController animated:YES completion:nil];
So I am assuming, the ViewController that contains the button is the root VC. You should change that with the SplitVC when tapping the button (add a nice animation), because the split should be the root of your app (it should not be presented modally). Hope this helps!
Edit:
It should look something like:
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.window.rootViewContrller = mySplitViewController;
You can also do this in your custom segue if you have one.
I am trying to push a new root controller to a navigation stack, but using a side reveal menu.
My app delegate has the following:
welcomeViewController = [[MyWelcomeViewController alloc] initWithNibName:#"MyWelcomeViewController" bundle:nil];
navController = [[UINavigationController alloc] initWithRootViewController:welcomeViewController];
navController.navigationBarHidden = YES;
// Then we setup the reveal side view controller with the root view controller as the navigation controller
self.revealSideViewController = [[PPRevealSideViewController alloc] initWithRootViewController:navController];
[self.revealSideViewController setDirectionsToShowBounce:PPRevealSideDirectionNone];
[self.revealSideViewController setPanInteractionsWhenClosed:PPRevealSideInteractionContentView | PPRevealSideInteractionNavigationBar];
// Then we make the window root view controller the reveal side view controller
self.window.rootViewController = self.revealSideViewController;
Once the welcome view controller is displayed, the user logs in. Once logged in the following process runs again from the App Delegate.
self.navController.navigationBarHidden = NO;
[self.navController setTitle:#"Home"];
[self.navController pushViewController:homeViewController animated:NO];
I then have a side view controller setup which is a table view with custom cells setup.
When a row is selected I need to push a new root controller onto the navigation controller. I try this by using the following in the table view for the cell selected.
MyAccountViewController *accountViewController = [[MyAccountViewController alloc] init];
[self.navigationController setViewControllers:[NSArray arrayWithObject:accountViewController] animated:NO];
Unfortunately this does not do anything. If I add the code to the App Delegate and then call the method from the table view controller then it works, however not from the .m file for the table view itself. Adding a log I can see the above is run, just does not do anything.
I am unsure if I need to do anything different on the above. For example, completely pop the views currently shown, then create the navigation controller and PPRevealSideViewController all over again. If I am supposed to, I am unsure how to pop all the current views to then push the new to the window, not from the AppDelegate.
The reason I do not want this in the App Delegate is because it is the incorrect way to approach this, and I would then need a separate method for each new root controller I would like to push from the menu, so the App Delegate would become very large.
Check UINavigationController.h:
#interface UIViewController (UINavigationControllerItem)
#property(nonatomic,readonly,retain) UINavigationController *navigationController; // If this view controller has been pushed onto a navigation controller, return it.
It means when you do myViewController.navigationController you will either get nil if myViewController is not pushed to any navController or the navController reference myViewController is pushed into.
As I understand your tableViewController is not pushed into the navController stack, that means you can't get the navController with tableViewController.navigationController. Instead you'll need to use anyViewControllerInTheStack.navigationController or if the navController is the rootViewController of your keyWindow, by
((UINavigationController*)[[UIApplication sharedApplication] keyWindow].rootViewController)
Add something like this to your AppDelegate.h:
#define XAppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
Now you can access any iVar of AppDelegate from any .m file in your project.
MyAccountViewController *accountViewController = [[MyAccountViewController alloc] init];
[XAppDelegate.navController pushViewController:accountViewController animated:NO];
Make sure you add the correct imports.
One more thing: It's good to pop the login window from your navcontroller once you are done Logging in.
Hope this helps.