Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can performSegueWithIdentifier be used with the AppDelegate?

I am working on an app that at launch checks for valid login credentials, and if they are found and not expired the main split view controller is displayed, and if not a login screen should be displayed.

Each part is working fine separately, but I am struggling with the best way at launch time to select the proper view to display.

I have tried setting up a modal segue from the root view controller, and in my application:didFinishLaunchingWithOptions: function in the App Delegate, calling this:

// Segue to the login view controller...
if (loginNeeded) {
    [self.window.rootViewController performSegueWithIdentifier:@"LoginScreen" sender:self];
}

This logically should work, but triggering segues from within the app delegate seems to be impossible.

What is the ideal place and technique for handling this?

like image 692
radven Avatar asked May 10 '12 18:05

radven


2 Answers

You could try a custom segue, as per this post hiding-a-segue-on-login-process.

Alternatively if you're desperate to have the login display before the split view controller loads try something along the following lines...

Create your login screen on the main storyboard as, say, a subclass of UIViewController. Make sure it is the initial scene (check Is Initial View Controller).

On the storyboard, create a new segue from your login class to the original SplitViewController. Give it an identifier, 'Load SplitViewController' and a segue custom class name which we'll call FullyReplaceSegue.

In your login class .m file, add code to be called once the user has logged in:

[self performSegueWithIdentifier:@"Load SplitViewController" sender:self];

Create the new segue class, based on UIStoryboardSegue and name it FullyReplaceSegue as per above.

.h file

#import <UIKit/UIKit.h>
@interface  : UIStoryboardSegue

@end

.m file

#import "FullyReplaceSegue.h"

@implementation FullyReplaceSegue

- (void)perform
{
    UIViewController *dest = (UIViewController *) super.destinationViewController;
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    window.rootViewController = dest;

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        UISplitViewController *splitViewController = (UISplitViewController *)dest;  // assumes we're transitioning to a UISplitViewController!
        UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
        splitViewController.delegate = (id)navigationController.topViewController;
    }
}

@end
like image 51
Andrew Kingdom Avatar answered Sep 21 '22 17:09

Andrew Kingdom


Here's how I did it.

In didFinishLaunchingWithOptions:

//save the root view controller
[[self window] makeKeyAndVisible];
UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController;
rootController = [[navigationController viewControllers] objectAtIndex:0];

Somewhere else in the app delegate:

[rootController performSegueWithIdentifier:@"fileSegueID" sender:self];

Then, in the storyboard, create a segue from the view that gets assigned as "rootController", to the desired optional view, and give that new segue the id fileSegueID. It takes some debugging to make sure the rootController variable gets assigned to the correct view.

like image 45
Scott Marchant Avatar answered Sep 20 '22 17:09

Scott Marchant