I have a login view controller that appears only if a user is not logged-in.
After being logged-in, the view is removed.
My question: how would I send an action to the view controller that requested the login view?
You may want to consider delegation or a target-action approach. In the end you will give the login view some information about your view controller so that it will be notified once login is complete.
Ex.
//Your view controller
loginView.delegate = self;
...
//loginView code
-(void)loginComplete
{
[self.delegate loginComplete:self];
}
Related
I am developing an application where i need to show a list as a menu(Courses,lessons,grade,logout) to the user. so even before this i need to show a login screen. Only upon successful and valid login i need to re-direct the user to the menu. So i have planned to develop a tabBar based application with 4 tabs. Here i am confused on how to add the login view controller even before the TabBar controller is loaded. I want the first tab to be selected every time. As of now i am adding my TabBar controller as a rootviewcontroller to my AppDelegate window and then presenting the login view controller as a modal view controller. But the problem here is even before the Login View controller is loaded, my courses view controller is loaded because the tabbarcontroller is loaded first. My actual requirement is i need to load the course view controller with the list of courses based on the inputs given in the Login View controller. But loadview of course view controller is loaded even before the load view of login view controller. so my list of courses is always the same irrespective of who logs in. I am confused here on how to move forward...Any suggestion here would be of great help...
So, a very quick example, could be; in your loginViewController you should have some method something like this:
//Call this after the user has done with the login
-(IBAction)remove:(id)sender{
AppDelegate *del=(AppDelegate*)[[UIApplication sharedApplication] delegate];
//Set some data based on the user's input (eg some property shared in the AppDelegate)
//del.dataEnterByTheUser=someData;
[del removeLoginView];
}
Then in your AppDelegate (assuming that now the rootViewController is the loginViewController) you could do like this (you can optimize the transition):
-(void)removeLoginView{
UITabBarController *tabVC=[[UITabBarController alloc] init];
ViewController *v1=[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
//v1.data=self.dataEnterByTheUser;
ViewController *v2=[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
NSArray *arrayVC=[NSArray arrayWithObjects:v1,v2, nil];
[tabVC setViewControllers:arrayVC];
[tabVC setSelectedViewController:0];
CGRect rectVC=self.loginViewController.view.frame;
rectVC.origin.y=self.view.frame.size.height;
[UIView animateWithDuration:0.3f delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.loginViewController.view.frame=rectVC;
} completion:^(BOOL finished){
[self.loginViewController.view removeFromSuperview];
self.loginViewController=nil;
self.window.rootViewController=tabVC;
}];
}
Also remember to set in each viewControllers's initWithNibName: the self.title to set the title on the tabItem.
No need to fiddle around with the rootViewController...
Just add the following code at the beginning of your viewWillAppear: method of the view controller which would normally appear first (most likely the VC you are presenting in the first tab):
[self.tabBarController presentModalViewController:loginController animated:NO];
Where loginController is obviously the view controller which manages your login screen. If you show it without animation, it will be the first thing visible when your app launches (after the default image disappears). I've used the same method to show a disclaimer page which the user must read before using the app. It's working just fine and made it to the store without problems.
Edit: In this solution, the loginController must dismiss itself once the user has successfully logged in:
[self dismissModalViewControllerAnimated:NO]; //Although you might do this animated, this time
You can just change the array of view controllers in the tab bar controller at runtime. That should be sufficient for your purposes.
I've written a small example. Try to login with the following credentials:
username: john, password: doe
username: pete, password: poe
You will see a different combination of tabs depending on the login used.
The example can be downloaded from my Dropbox: http://dl.dropbox.com/u/6487838/LoginTabExample.zip
I am building an iOS 5 app with oauth integrated. My storyboard consists of a container NavigationController, with a rootViewController, and two viewControllers segueing from the rootView. When the app is launched, i perform a check to see if an access token is present, and direct the user accordingly.
// rootViewController.m viewDidAppear (i need to perform this check anytime the user is brought to the root view, say for e.g. he logs-out.)
if (accessToken) {
BOOL didAuth = [GTMOAuthViewControllerTouch authorizeFromKeychainForName:#"app name: service" authentication:accessToken
if (didAuth){
//perform segue to main User View (which is a TableViewController)
}
else{
//perform segue to sign-in controller, and direct the user to main view from there.
}
}
I have a couple of questions:
Is such a setup 'valid' as per Apple's Interface Guidelines?
I noticed that the prepareForSegue method in rootViewController gets called after the mainUserView's (which is a TableViewController) viewDidLoad. Is this standard behavior? I understand that this is the case for popovers, but for segues from a standard ViewController to a TableViewController?
Thanks!
May be this one is easy..,
I am new to iphone development.. My question is :
I want to present a new screen after successful login, My app displays a Login screen to the user, and I have implemented the login logic in -(IBAction)login:(id)sender method when we click on the submit button.., After successful login, a new screen must be presented.
If you are using a Navigation controller you can push the new view controller onto the stack and display it through pushViewController: animated: method. You can also use presentModalViewController: animated: Or you can just add the new view as the subview of this view by [self.view addSubview:secondView];
you can refer
Apple's UIViewController reference. Short and sweet (relatively).
View Controller Programming Guide for iPhone OS.
UPDATE
Implement this in your current view controller
- (IBAction)buttonClicked
{
if(validated)
{
// code to show goes here.
}
}
In my iphone app, I am having a twitter page where the user can update his/her status.
Here, the problem is that the user has to click the button on view (say view A) and go to next view(say view B).
On that view (view B), the modal view then appears where in the user can add his authenication details and then submit.
Now I want that the modalview should appear on the that view (view A) rather than switching to another view (view B).
What should I do?
Please Help and Suggest
Thanks
The functionality can be added on View "A" itself. Once you finish up adding required Framework and classes you can add this code in the button action method.
-(IBAction) showTwitter:(id)sender{
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller) {
[self presentModalViewController: controller animated: YES];
}
else {
//comes here when user has already keyed in His credentials
//can add code here
}
}
This link might be of help to you.
http://mobile.tutsplus.com/tutorials/iphone/twitter-api-iphone/
In Obj-C / iOS. Our UI design calls for an initial screen with options to register or log on. After doing either of these, the user data is saved to the phone and a the tabBarController is shown. However, tapping on the tabBar at the bottom takes the view back to the "log on or register" screen. Is it possible to change the root view controller in a tabBarItem's hiearchy?
What you have to do is have a UIViewController called "LoginViewController" as your Root Controller but this controller does not have a UITabBar it's just a controller with the Login UIView. And also have your UITabBarController with all of its content set but don't include the Login just have your basic content.
After the user logs in you show the UITabBarController with its content.
-(void) LoginUser {
// Load UITabBarController
YourAppDelegate *app = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
[app.window addSubview:aTabBarController.view];
}
where app is your *app Delegate.
You can't change the root, but you can solve this a few ways. Perhaps the simplest is in your viewWillAppear method check to see if the user is logged in, if so, immediately load (using navigation controller, modally or just add a subView depending on your app's structure), the regular logged in view without animation, then the user will never see that this happened. (You might choose to do it the other way, only load the login screen if the user is NOT logged in.)
I am using a navigation controller instead of a tab bar controller, but the concept I think is similar or the same. I did not want the user being able to "track back" to the log in screen once they had logged in.
I built my log in view as a modal view that is called in the ViewDidLoad of the main app view controller if the user is not logged in:
if (isUserLoggedIn == NO) {
[self performSegueWithIdentifier:#"logInUserModalSegue" sender:self];
}
The main view loads briefly and then the LogIn modal view animates up, covering everything.
When the user hits log in, I check the credentials and then dismiss (or not) the modal controller, like this:
if (logInStatus == YES) {
[[self presentingViewController] dismissViewControllerAnimated:YES
completion:NO];
} else {
self.errorDisplay.text = #"Sorry, there was an error logging in.";
}