Xcode - Logout button - iphone

Apparently, I have one LoginViewController and a StartUpController.
LoginViewController has functionality to authenticate user and register new user (presentModalViewController). Once the user has logged in, my system will display StartUpController.
Inside this StartUpController, I have everything such as TabBarController, NavigationController, etc. This StartUpController is actually handling 5 different views.
My question is: what should I do to remove all of my views when my user click on "LogOut" button from one of my view?
I want to show my LoginViewController again.. but at the same time, remove the StartUpController view and all its views.
Please teach me how to do this:

If your authentication view is your root view controller's view, use the -popToRootViewControllerAnimated: method on your navigation controller reference, e.g.:
[myNavigationController popToRootViewControllerAnimated:YES];
Assuming you're not doing any weirdness with view controller ownership, the navigation controller will release the children view controllers (which, in turn, should release their views and other properties).

Related

Xcode: Display Login View in applicationDidBecomeActive

In my app I would like to show a login screen - which will be displayed when the app starts and when the app becomes active. For reference, I am using storyboards, ARC and it is a tabbed bar application.
I therefore need to do the process in the applicationDidBecomeActive method:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if ( ... ) { // if the user needs to login
PasswordViewController *passwordView = [[PasswordViewController alloc] init];
UIViewController *myView = self.window.rootViewController;
[myView presentModalViewController:passwordView animated:NO];
}
}
To an extent this does work - I can call a method in viewDidAppear which shows an alert view to allow the user to log in. However, this is undesirable and I would like to have a login text box and other ui elements. If I do not call my login method, nothing happens and the screen stays black, even though I have put a label and other elements on the view.
Does anyone know a way to resolve this? My passcode view is embedded in a Navigation Controller, but is detached from the main storyboard.
A variety of answers finally led me to an answer which doesn't seem too complicated so I will post it here - and it actually looks really good if I am honest.
Firstly, my password view is embedded in a Navigation Controller (Editor -> Embed In) and this is connected to the main tab bar controller using a modal segue with an id, in my case 'loginModal'.
In the applicationDidBecomeActive method put something like this:
[self performSelector:#selector(requestPasscode) withObject:nil afterDelay:0.2f];
And then put this function somewhere in the App Delegate
-(void)requestPasscode{
if ( /* If the user needs to login */ ) {
[self.window.rootViewController performSegueWithIdentifier:#"loginModal" sender:self];
}
}
This will present your login view whenever the app begins or enters the foreground (for example, when switching apps).
NOTE: The above line will not work if the root of your app is embedded in a navigation controller.
There are however two bugs;
If the user was previously viewing a modal view when they dismissed the app
If the user dismissed the app on the password view.
Both of these cause the app to crash so the following line goes in the applicationWillResignActive method.
[self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
It basically dismisses all modal views that are presented. This may not be ideal, but modal views are more often then not, used for data entry and so in many cases, this is a desired effect.
You should init PasswordViewController viewcontroller from xib or if you store UI in Storyboard you should use Segue for present this controller.
I can't say about another parts but that part seems to me very weird.
My passcode view is embedded in a Navigation Controller, but is detached from the main storyboard.
in storyboards you can store view controllers and view inside of view controllers so it's not good to store some view outside of viewcontroller because you will not be able to load this view from storyboard after receiving memory warning. Please correct me if I didn't get what do you mean.
If we are going by your way there is no difference load PasswordViewController at applicationDidBecomeActive or at your first view controller at Storyboards because you calling present view controller from first loaded view controller. So you can do it in your first view controller. Also you can store some hidden view inside of your first viewcontroller and show this view if the user needs to login.
I tested it. So at first your controller become loaded and then you got method applicationDidBecomeActive. So it's better to put your code inside -(void)viewDidAppear:animated method of your first viewcontroller.
Best regards,
Danil

Returning back to the viewController with segues

This is my Hierarchy
Navigation Controller --> Login Controller View --- > Register Controller View
--> My Small Internal LeaderBoard View
Now I am using segues (Push) to go to either LoginControllerView or LeaderBoardView
Once I am on LoginControllerView and then RegisterControllerView I am using this code
[self dismissViewControllerAnimated:YES completion:nil]
However instead of returning me to LoginControllerView it is returning me back to NavigationController.
How can I return to my LoginController
I am transitioning from Login to Register through PUSH segue and I have named the segue as "Register"
From Login To RegisterController I am using this code
[self PerformSegueWithIdentifier:#"Register" sender:Self]
However, I can see from RegisterView connection inspector that its viewController reference StoryBoard Segue is "Login" .. I am transitioning from Login to Register with Register Segue, How can my RegisterController has Login segue as reference?
You did not say how RegisterControllerView is being presented. If it is being pushed on the navigation controller stack, then why not call:
[self.navigationController popViewControllerAnimated:YES];
If you are doing something special, then you need to say what special thing you are doing.
Also, note that if you find where a view controller is trying to dismiss itself, then you should at minimum revisit your design to see if that's really the best thing to do. A view controller may not know how it was presented, so it may not know the best way to dismiss itself either.

ios best practices- navigation and tab controllers and push/pop

My problem:
My app requires a user to be logged in, so the first view I show is a login view. If we are logged in, then we show the app view, which is a tab bar controller. One of these tabs is account info + logging out. On logging out, I want to go back to the the login screen.
My solution:
The root view is a navigation controller, which holds the main view. The main view is transparent, just says are you not logged in? Push the account screen onto the stack. If logged in, push the tab controller view onto the stack. Each tab in the tab controller is a navigation controller. Clicking on the account tab pushes the account view on the account view onto the stack. The account view has a logout button, which pops up 2 views (and doesn't work):
// Go to main view (2 views up) to show default login screen (as we won't be logged in anymore)
UINavigationController *navController = self.navigationController;
[navController popViewControllerAnimated:NO];
[navController popViewControllerAnimated:YES];
What I think is the problem:
The navigation controller that I have on the top level is not the same as the lower level navigation controllers in the tab controller.
My problem seems fairly typical, but my solution seems really clunky. This can't be the best way to do it! Any advice?
Try something like this? It seems convoluted but let's try it.
[self.navigationController popViewControllerAnimated: NO];
[self.tabBarController.navigationController popViewControllerAnimated: YES];

iPhone Login -> tabbarcontroller

I have created an app and a login and would like to join them together with no luck. The app has a tabbarcontroller with navigationcontrollers via tableviewcells to drill down to other views of the app.
As I am having no luck in joining the two. I have tried to build on from the login that I have done. I can push to a new view but it does not show a tabbarcontroller etc on the next view. I have seen various forums with people having this problem as well.
So, my question: How can I make a new page (login) open to a TabBarController instead of a view (in the middle of my app, not at the launch)?
Does anyone out there know how to solve this issue?
Use navigation controller in tab bar controller. lets say the navigation controller is its first view controller. Now when the root view controller of the navigation is being displayed, you can see the tab bar. Now if you keep pushing new view controllers in this navigation controller, the tab bar wont hide itself.
However if you present some view controller modally, it would hide itself.
As far as login is concerned, i will check if user has logged in or not. if no, then i would set the root view controller of navigation controller as loginviewconroller else some home page.
I would check the if the user is logged in in the first viewController that get loaded.
From there I would present the loginViewController via the presentModalViewController method.
The use will not see the tabbar if you set the withAnimation:NO.
Now just dismiss the login viewcontroller when the use is logged in.
One could also send a notification that the is logged in, so that viewcontrollers can update them self for the no logged in user.

Lost In Views - Best Way to Transition Between UIViewControllers

I have an iPhone / iPad application that manages its numerous view controllers via a UINavigationController and UITabViewController. The UINavigationController handles the majority of the user interaction and the UITabViewController handles user settings/preferences.
My app delegate initializes the UINavigationController and pushes the first view controller. Settings (the UITabViewController) can be accessed via a button on the navigation controller's menu bar; the user can return to the main application (the UINavigationController) via a button on the UITabViewController.
My question is: what should I be doing with the UINavigationController (and its stack of view controllers) when I show the UITabViewController and vice-versa? Is there any reason to remove/release/recreate each parent controller as the user switches between the two, or should I be adding/removing each parent controller's view to my app's window?
It seems that the first option would be more mindful of memory/resources, however these benefits might get overshadowed by the processing cost to re-alloc/init the view controllers each time.
Thanks.
You do not have to manage the navigation controller's stack manually. What I would do is present your settings view controller as a modal view. You would do this at the navigation controller level.
Assume that settingsViewController is a property of your main view controller.
self.settingsViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal
[self.navigationController presentModalViewController:self.settingsViewController animated:YES];
I assume you mean UITabBarController.
If your navigation view would show up in the tab view for a tab item, I would suggest let the tab bar controller to be the root view controller of your application (and therefore always seen in the app).
If your navigation view is the main view, and the user simply opens up the tab bar view for settings etc. and will return for the navigation view, then modally presenting the tab bar controller is the right way.
In the first case (the navigation controller IN the tab bar controller), you would not care for adding/removing or allocating/releasing views as the UIKit will manage it for you.
In the second case you may create a tab bar controller when you want to show it. presentModalViewController will retain the view controller so you can release it immediately after you send the message. If you want to hold the view controller then you create one when the application is loaded and retain it in the navigation controller (and the navigation controller will always remain in the memory).