iPwnTech
iPwnTech

Reputation: 545

Present modal view controller over view controller at launch

In my AppDelegate.m, I have the following code to set the initial view controller for the user at launch, depending on whether there are credentials stored in the keychain.

If the user does have credentials stored, the app will instantiate the main user interface with storyboard id, balancescreen. This works fine with the code below.

If the user does not have credentials stored, I would like to present the login view controller with storyboard id, loginscreen, modally over the top of balancescreen. When correct credentials are entered, the view controller will be dismissed (I have already handled this), with the user shown the main interface. This is what I need help with, finding a solution to do this without glitching the application.

This is the code I currently have:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // grabs password for the only account
    // (there shall always only be one set of credentials stored so this will work)

    NSString *password = [SSKeychain passwordForService:@"MyOpal" account:[[SSKeychain accountsForService:@"MyOpal"][0] valueForKey:@"acct"]];


    // if password has a length (aka user has previously used the application with credentials in keychain), direct to the app
    // if password has no length (aka does not exist because user has not used the application before), direct to login screen

    if (password.length > 0) {

        self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"balancescreen"];

        self.window.rootViewController = viewController;
        [self.window makeKeyAndVisible];


    } else {

        // do something here to present login view controller modally over the top of the main interface (with storyboard id, 'balance screen')
        // therefore, when the user logs in, the login view controller will dismiss, with the user greeted at the main interface


    }

    return YES;
}

Edit: This is my storyboard set up:

enter image description here

Upvotes: 1

Views: 1659

Answers (2)

DarthMike
DarthMike

Reputation: 3481

Don't change the rootViewController in your application. Make the rootViewController receive the request to navigate to login or to application.

Changing the rootViewController of the window is bad practice as you need to do animations manually. A storyboard flow would look like this:

Storyboard

Upvotes: 2

nburk
nburk

Reputation: 22731

Try this:

if (password.length > 0) {

    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"balancescreen"];

    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];


} else {

    // go on as before
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"balancescreen"];

    // instantiate the LoginViewController
    LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];

    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];

    // present the LoginViewController modoally with viewController as presenter
    [viewController presentViewController:loginViewController animated:NO completion:nil];

}

Obviously I am assuming that your UIViewController that handles the login is called LoginViewController. If that's not the case, just go on and adjust its name in your code :)

Anyway, for this kind of situation I would rather recommend you to not present the login modally. A better approach is to actually change the rootViewController property of your application\s main UIWindow.

That could look like this in your case:

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    if (password.length > 0) {
       UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"balancescreen"];
       self.window.rootViewController = viewController;
    } 
    else {
       LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
       self.window.rootViewController = loginViewController;
    }
    [self.window makeKeyAndVisible];

Upvotes: -1

Related Questions