I am playing around with the new iOS 5 features and trying to rewriting one of my apps as pure iOS 5 app using the new storyboarding feature.
To cut a long story short,
I have solved it by putting a login view without any segues (to or from it) like in the screenshot below:

Then, I used a custom class in the tab bar controller to show it whenever I need it.
In the tab bar controller class, I use 'viewDidLoad' to fire up the login view. To show the modal view, I do have a singleton thingy that stores some state, say BOOL isAuthenticated, where I do the magic:
- (void) performLoginIfRequired: (UIViewController *) source {
if (!self.isAuthenticated) {
NSLog(@"Is not authed");
UIStoryboard *storyboard = [UIApplication sharedApplication].delegate.window.rootViewController.storyboard;
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:@"loginScreen"];
[source presentModalViewController:loginController animated:YES];
} else {
NSLog(@"Is authe");
}
}
And, in my case, I wanted it to be shown when the app first starts, but also when it enters foreground again. So, I registered my tab bar controller with the notification center, so I get notified if the app is coming back:
-(void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
In the willEnterForeground method, I do:
-(void) willEnterForeground: (NSNotification *)notification {
[[myStateThingy defaultState] performLoginIfRequired:self];
}
After trying many different methods, I was able to solve this problem with this:
-(void)viewWillAppear:(BOOL)animated {
// Check if user is already logged in
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([[prefs objectForKey:@"log"] intValue] == 1) {
self.view.hidden = YES;
}
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Check if user is already logged in
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([[prefs objectForKey:@"log"] intValue] == 1) {
[self performSegueWithIdentifier:@"homeSeg3" sender:self];
}
}
-(void)viewDidUnload {
self.view.hidden = NO;
}
I had this same issue, and I solved it simply by doing the following: Instead of trying to segue to a login screen(modally or push), I made the login screen my root view controller. In the login view controller's viewWillAppear method, I check if someone's logged in already. If so, I push my home screen:
// mutableFetchResults is an array with my persistent Credentials object
if ([mutableFetchResults count] > 0) { // Someone's already logged in
[self performSegueWithIdentifier:@"Home" sender:self];
}
Also, in the Home screen view controller's viewWillAppear method, I hid the back button with this line, so the user can't go "back" to the login screen:
self.navigationItem.hidesBackButton = YES;
Finally, every page of my app has a "Sign Out" bar button on the top right. Signing out and putting the login screen up was as simple as this:
- (IBAction)signOutButtonPressed:(UIBarButtonItem *)sender {
MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate signOutCurrentUser]; // this method in my app delegate deletes the current Credentials
[self.navigationController popToRootViewControllerAnimated:YES];
}
Hope that was simple enough!
It sounds like you need to use the performSegueWithIdentifier method. Make sure both views are in the same storyboard, link them together using a Push segue, and give that segue a name. Then, from your first view controller's code simply call the performSegueWithIdentifier to perform a manual segue.
Hope this helps!
See also: Conditionally following a segue
Cheers, Jesse L. Zamora