prepareForSegue called after viewDidLoad in segue from ViewController to TableViewController - ios5

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!

Related

Creating a conditional segue [duplicate]

This question already has an answer here:
Proper way to do "conditional segue" in iOS5
(1 answer)
Closed 9 years ago.
I want to have a main view controller which checks if a user has already logged in. If so, it segues to a tab view controller. If not, it segues to a login view controller which handles the login and then segues to the tab view controller.
To test just the segue aspect of the a feature out, I created a separate project. I have created 3 view controllers - all subclasses of UIViewController. One of them is a main view controller and the other two are simple view controllers to which the conditional segue should happen.
I read about creating "triggerless" segue in the thread how to apply condition based custom segue in storyboard
How do I create two triggerless segues such that I manually choose to execute only one of the two at run time depending on if the user is logged in or not? Or is there a different way of achieving this rather common scenario?
How do I create two triggerless segues such that I manually choose to execute only one of the two at run time depending on if the user is logged in or not?
Create the first triggerless segue leading to the logon screen; give it an identifier, say, needLogin
Create the second triggerless segue leading to the tab view; give it an identifier, say, whenLoggedIn
Define an action in the main view controller, and put this code in its associated method:
// This is attached to the button on the main screen
-(void)onCheckLogin {
if (userIsLoggedIn) {
[self performSegueWithIdentifier:#"whenLoggedIn" sender:self];
} else {
[self performSegueWithIdentifier:#"needLogin" sender:self];
}
}
I assume you know how to check whether is logged in or logged out.
Try with this :
if (loggedIn) {
[self performSegueWithIdentifier:#"GoToViewController1" sender:self];
} else if (loggeOut) {
// Segue to Login viewController
[self performSegueWithIdentifier:#"GoToLoginViewController" sender:self];
}
Note : In stoyboard, you have to create segue from your viewController only, not from a UIButton or any other object from where segue is possible.

UINavigationController - Run Code Before Popping View Controller

I have a stack of UIViewController subclasses. Each modifies a NSManagedObject model. Many of them also present their own modal view controllers.
I need to save changes to the NSManagedObjectContext when a user either 'pops' the view controller or pushes the next view controller.
Currently, I'm hiding the default back button and setting my own UIBarButtonItem with a target of self and a custom action.
This works okay, but ideally, I want to use the default back button and run code before the pop. Is there a way I can run my own code before the pop?
(I'd prefer not to put code into viewWillDisappear as persisting to disk can be expensive and this method can also be triggered by modals being displayed by view controller.) Can it be done?
You can do it in viewDidDisappear, after checking that self is either 1) the second last element in self.navigationController.viewControllers (the case where the next VC just got pushed) or 2) self.navigationController is nil (the self VC just got popped).
Yes.. Navigation controller has a delegate which indicates when a view controller popped or pushed.. You can use that to do your task...
Add following method in your code:
- (void) viewWillDisappear:(BOOL)animated{
//your code here
}
I use viewWillDissappear to make any changes persistant.
If required i Use viewWillAppear to recoginze any changes (reload the data) that may have taken place while other puhed view controlers did their work.
For pop check isMovingFromParent in viewWillDisappear
func viewWillDisappear(_ animation:Bool){
super.viewWillDisappear(animation);
if isMovingFromParent {
// your code here
}
}

iPhone - sending an action from one UIViewController to another?

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];
}

UIViewController and UITabBarController app - viewDidLoad called only once

My current application consists of a UITabBarController with 4 different tabs and a UIViewController. My tabBarController is the rootController and the UIViewController is primarily being used for my user login view. When the application loads both views are loaded with the login view covering the tabBar.
I have added some logging to my viewDidLoad method for the loginViewController. I see this method being called on initial launch. Once the user successfully logs in, the tabBarController view is now viewable. I setup an action to logout from the tabBarController. This method sets user/pass to nil and calling a delegate method to load my loginView again.
-(void)setLoginView
{
[window addSubview:loginController.view];
}
I'm adding some checks but nothing is firing because viewDidLoad (in loginViewController.m)never gets called again. When logging out my text fields still have the user/pass that was entered when I first logged in. So one of my checks is to reset the text fields to nil etc..
I may be using the wrong terminology here but is there anyway to "refresh" this loginController where the viewDidLoad method is called every time the user will log out?
Also for the record. I can't thank everyone enough that has helped answer my previous questions. It has really helped and I appreciate it.
Thanks
Maybe try using -(void)viewWillAppear:(BOOL)animated {...} instead of viewDidLoad?
viewDidLoad will be called only once for each time when the view has been inited. I'm not sure if doing loginController.view = nil will cause view to unloaded or not, but I think it should work so next time you access view property the view will be loaded again.

How to know when a UIViewController view is shown after being in the background?

In iOS4.2/iPhone4
Click icon to launch app (some view
controllers view is displayed)
Click iPhone Home button (return to
home screen)
double click Home button
Select previously launched app from
the selection
Now I can see that my app delegate gets a message "applicationDidBecomeActive" when its selected after the last step, but how does my viewController (the one who's view is currently displayed) know?
viewDidLoad was already called, so that isn't called again. viewWillLoad is not called again.
Can't seem to figure it out. Reason I'm asking is I want to check to see if any Settings changes were made, but would like to do that in the view controller cause that's the thing that cares.
The answer is here: Handling applicationDidBecomeActive - "How can a view controller respond to the app becoming Active?"
Use NSNotificationCenter to get notified of UIApplicationDidBecomeActiveNotification events in your view controller.
in you're appDelegate applicationDidBecomeActive put this :
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UINavigationController *navc = (UINavigationController *)[tabBarController selectedViewController];
UIViewController *topvc = [navc topViewController];
if ([topvc respondsToSelector:#selector(viewControllerDidBecomeActive)])
{
[topvc performSelector:#selector(viewControllerDidBecomeActive)];
}
}
This gets the viewController that is being seen on screen. You just have to implement viewControllerDidBecomeActive on every viewControllers ;)
In the appDelegate applicationDidBecomeActive set a boolean property marking that it just appeared from background.
Then in your viewcontroller, specifically in the viewDidAppear override, check for the appDelegate property, if its true then you know it has come from the background, otherwise it has just appeared as normal. BTW Afterwards, set the boolean property to false for neatness.
EDIT-
You would have to call viewDidAppear manually in the applicationDidBecomeActive unless you were re-creating your navigation stack. If you were able to get a pointer to the current visible view controller, then calling viewDidAppear should be a no fuss approach as all view controllers have this method. You wouldn't need any delegates or etc.