4

I have a root view controller that presents an authentication view controller. Once the user authenticates I need to dismiss the authentication controller and present a user specific controller (example: on boarding controller, normal user controller, pro user controller). What I would like to happen is when the authentication controller is animated down, the appropriate controller is revealed (as if it was presented before the authentication controller).

These are the two solutions I have tried so far. Both show the root view controller between transitions.

  1. In the -viewDidAppear of the root view controller I present the appropriate controller (authentication or user specific controller).

  2. I have tried to dismiss and present the two controllers using the following:

    [authenticationController dismissViewControllerAnimated:<NO|YES> completion:^{
        [userController presentViewController:viewController animated:animated completion:nil];
    }];
    

TLDR:

I have a modal view hierarchy that starts like this rootViewController->viewController1 and I want to transition to rootViewController->viewController2 where viewController1 animates down to reveal viewController2

Mischa
  • 15,816
  • 8
  • 59
  • 117
datinc
  • 3,404
  • 3
  • 24
  • 33
  • See this: http://stackoverflow.com/questions/19962276/best-practices-for-storyboard-login-screen-handling-clearing-of-data-upon-logou/21877460#21877460 maybe helps you, covers the whole concept of login process. – Dimitris Bouzikas Feb 24 '14 at 23:19
  • Its not quite what I am looking for. That solution knows what the users root controller should look like. In my example I am unsure what the user controller is going to be until after the authentication process. – datinc Feb 24 '14 at 23:42

3 Answers3

0

Once the user is done authenticating set a flag of meaningful value to you then lets say once they hit OK or Submit you can check and set the flag.

From there you will instantiate one of the three view controllers and push it in the navigation stack - do this using the storyboard if you like by setting the storyboard ID to a value and then instantiate the VC with storyboard ID.

If you need more clarification or if this isn't the right track let me know.

A

EDIT : once you instantiate you will need to present the view controller with animation

Andy
  • 479
  • 7
  • 20
  • This would mean the authentication controller is still part of the modal view hierarchy. That is what I am trying to avoid at all costs. – datinc Feb 25 '14 at 00:00
  • How about a forced segue to the next VC with an animation OR you can set your nav controller with all the views in a stack and just pop to the level you need (although that may not be what you want either...) – Andy Feb 25 '14 at 00:08
0

The documentation for -dismissViewControllerAnimated:completion: states:

If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack.

So one way to achieve that kind of behavior would be to arrange your view controllers like this:

Storyboard Screenshot

You put the view controller vc2 that you want to show after the login at the first position. In vc2's -viewWillAppear method you forward to vc1 in case the user is not logged in:

- (void)viewWillAppear {
    if (!userLoggedIn) {
        UIViewController *vc1 = [[YourViewControllerClass1 alloc] init];
        [self presentViewController:vc1  animated:YES completion:nil];
    }
}

When the user taps the Show Login VC button in vc1 you present the login view controller from there:

- (IBAction)touchUpInsideShowLoginVCButton:(id)sender {
    UIViewController *loginVC = [[YourLoginViewControllerClass alloc] init];
    loginVC.delegate = self.presentingViewController;
    [self presentViewController:loginVC  animated:YES completion:nil];
}

You also set vc2 as loginVC's delegate here because you need a reference to vc2 in your loginVC. (You need to define a property delegate in the .h file of loginVC:)

@property (strong, nonatomic) UIViewController *delegate;

Finally, when the user taps the Login button and the login is successful you dismiss two view controllers at the same time (by simply calling -dismissViewControllerAnimated:completion: on vc2 which is the lowest in the hierarchy) in order to reveal vc2 for the first time.

- (IBAction)touchUpInsideLoginButton:(id)sender {
    // ... your login code
    if (loginSuccessful) {
        [self.delegate dismissViewControllerAnimated:YES completion:nil];
    }
}
Mischa
  • 15,816
  • 8
  • 59
  • 117
0

I think presentViewController don't support to insert a viewController below the top presentedViewController, which is the authentication controller here. If you have a navigationController for rootViewController, you can try pushViewController:animated: before do dismiss authentication controller, and push animated can be NO;

simalone
  • 2,768
  • 1
  • 15
  • 20