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.
Related
i initialize tables, data etc in my main ViewController. For more settings, i want to call another Viewcontroller with:
DateChangeController *theController = [self.storyboard instantiateViewControllerWithIdentifier:#"dateChangeController"];
[self presentViewController:theController animated:YES completion:^{NSLog(#"View controller presented.");}];
And some clicks later i return with a segue (custom:)
NSLog(#"Scroll to Ticket");
[self.sourceViewController presentModalViewController:self.destinationViewController animated:YES];
My Problem:
After returning to my main ViewController, viewDidLoad is called (everytime).I read, that the ARC releasing my mainView after "going" to the other ViewController and calling the viewDidUnload Method, but i want to keep all my data and tables i initialize at the beginning..
Any solution? Thank you very much!
The problem is that you are doing this:
main view controller ->
date change controller ->
a *different* main view controller
In other words, although in your verbal description you use the words "returning to my main ViewController", you are not in fact returning; you are moving forward to yet another instance of this main view controller every time, piling up all these view controllers on top of one another.
The way to return to an existing view controller is not to make a segue but to return! The return from presentViewController is dismissViewController. You do not use a segue for that; you just call dismissViewController. (Okay, in iOS 6 you can in fact use a segue, but it is a very special and rather complicated kind of segue called an Unwind or Exit segue.)
If you do that, you'll be back at your old view controller, which was sitting there all along waiting for your return, and viewDidLoad will not be called.
So, this was a good question for you to ask, because the double call of viewDidLoad was a sign to you that your architecture was all wrong.
I think you're taking the wrong approach - viewDidLoad is supposed to be called when it is called - it's a notification to you that the view is being refreshed or initially loaded. What you want to do is move that table initialization code somewhere else, or, at least, set a Boolean variable so that it is only called once. Would it work to create an object that has your table data when viewDidLoad is first called, then to check it to see if it's already been called?
I am using storyboard,in which i have three view controllers. I want to go to 2nd view controller from first without any touch(so i used timer .)
I added following code to timers method:
[self presentModalViewController:anyViewControllerRef animated:YES];
or
[[self navigationController] pushViewController:anyViewControllerRef animated:YES];
but both the times i got blank screen after timers interval (even i got the logs perfectly, means the logs which i added in 2nd ViewControllers class but no visuals correctly)
What should i add to timers method to perform scene transition?(so able to see whatever i have added on next ViewController)
Just for your own reference, the reason why this was not working for you was because you were "creating" a viewcontroller of whatever type you had and showing this "newly created" controller, of course this one doesnt have any visuals on it because the interfacebuilder controller is NOT linked to this one.
Your solution means that instead of creating an instance of the anyViewControllerRef you are asking the storyboard to give you the one it holds (the one with the visual elements you added).
By the way almost 90% of the time you want to present modally a view controller under ios for iphone, push is only used for ipad or for navigationviewcontroller if i remember correctly.
Need to add identifier to next view controller and following code in timers method :
anyViewControllerRef = [self.storyboard instantiateViewControllerWithIdentifier:#"identifierName"];
[[self navigationController ] pushViewController:anyViewControllerRef animated:YES]
I have a screen in which a user can choose a set of meals - once the meals have been chosen the application fetches results form a database and displays a list of them. Now, I would like to implement a condition to decide whether the next screen should be loaded or not - ie. if there's no internet connection then show an alert and don't display the next screen etc.
I've implemented a system to check whether there is an internet connection or not but I'm not sure how and where to decide of the next screen should be loaded. Any ideas?
Thanks,
1.5 other options:
If you're willing to split stories and nibs, just load up a nib when you want/need to.
If you want to stick to stories exclusively, just load up another story when you need to. Same thing as loading a nib:
UIStoryboard *otherStoryboard = [UIStoryboard storyboardWithName:#"OtherStory" bundle:nil];
UIViewController *otherController = [otherStoryboard instantiateInitialViewController];
[self.navigationController pushViewController: otherController animated:YES];
Once you know in your code whether you want to display the next screen or not, can you not just add an if statement that either loads the next screen or displays a warning that there is no connection?
if (hasConnection) {
// Show next screen
} else {
// Show warning
}
You supposedly have an action that is being fired when the user selects some meals, haven't you? In this action you'd call [UINavigationController pushViewController:nextViewController animated:YES] or something like this. Put this function call into the condition of your preference, and show a popup otherwise.
I solved this issue using the answers from:
Prevent segue in prepareForSegue method? by linking the segue to my main view controller, then attaching an IBAction to the button that was originally the segue initiator and performing the logic in that method. If it all cleared then I call [self performSegueWithIdentifier:#"results" sender:self];
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!
I'm creating a very simple sample app to show how preferences will work with a new application I'm working on. The process is very simple: create a UINavigationController in IB, assign it the View Controller that will be the root view controller, and push a new view controller onto the navigation controller's stack when didSelectRowAtIndexPath is called.
I've read as many related topics to this as I can find and never found a satisfactory answer.
The problem is that when the back button is pressed, the navigation controller animates back, but the view itself doesn't change back, meaning it's not getting popped.
This is the code I use to push the new view controller onto the stack. It's pretty standard. I added the NSLog to make sure it's only getting hit once.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section != 0)
return;
NSLog(#"didSelectRowAtIndexPath\n");
PrefsListTableViewController *prefsListTableViewController = [[PrefsListTableViewController alloc] initWithNibName:#"PrefsListTableViewController" bundle:nil];
[self.navigationController pushViewController:prefsListTableViewController animated:YES];
[prefsListTableViewController release];
}
To check if the viewWillDisappear call is hit on the second view, I added this to my PrefsListTableViewController:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
NSLog(#"ptvc viewWillDisappear");
}
This never gets hit.
First, I was under the impression that you don't need to code anything to handle the back button since the UINavigationController should pop the stack for you automatically when you press the back button. I can show that with a sample app I have which does what I'm doing, but the sample is code only. The code is from Erica Sadun's iPhone Developer's Cookbook code, recipe 11-11. Her code is here:
https://github.com/erica/iphone-3.0-cookbook-/tree/master/C11-Tables/11-Disclosure%20Chevrons
If you look at her code, there are no .xib files, and everything is handled without the need to code the back button at all. The view controllers are pushed in code, and popped, seemingly, without code. I prefer to use .xib files and everything SHOULD be working the same way, but it's not.
Second, I put in NSLog statements to show that in fact, the root navigation controller has the two view controllers.
2011-11-18 11:14:36.355 TableViewTest[58011:207] didSelectRowAtIndexPath
2011-11-18 11:14:36.358 TableViewTest[58011:207] ptvc viewWillAppear (
"<TableViewController: 0x8923d40>",
"<PrefsListTableViewController: 0x8927a20>"
)
2011-11-18 11:14:36.717 TableViewTest[58011:207] ptvc viewDidAppear (
"<TableViewController: 0x8923d40>",
"<PrefsListTableViewController: 0x8927a20>"
)
So you can see that the view controllers are pushed and in the proper order.
That leads to one question: why isn't PrefsListTableViewController getting popped when the back button is pressed? If anyone needs any more info, please let me know.
Have you extended UINavigationController Class? I did and had the same issue. Apparently, according to apple docs, your not supposed to extend that class...