Search code examples
iosauthenticationmodal-dialoguisplitviewcontroller

Login View Controller over modal View Controller


The following scenario:

My iPad app has a SplitViewController as it's main VC. After starting the app (new or from background) I have a fullscreen login view that (obviously) disappears after entering the correct password.

The problem:

After login, I want to present the exact same screen that was there BEFORE moving to background. This works fine UNLESS there is a modal view on top of the split view (like settings etc).

What I tried:

In AppDelegate I store my self.window.rootViewController, make the login vc as my root vc and after login I set my stored root VC as actual root VC. But then the (modal) settings view is not visible and can not be opened again (Warning: Attempt to present VC on SplitVC which is already presenting VC). In fact, no other modal view can ever be opened (unless app is properly closed).

Second try: Instead of setting the login VC as root VC I presented it as a fullscreen modal view on top of my split view. This yielded the same error message as the first try but a different result. After entering background mode the login VC won't be presented at all (since there already was a modal view).


Solution

  • What I did was the following:

    Create a property that can store my modally presented VCs (they are all embedded in a UINavigationController)

    @property (nonatomic) UINavigationController *navController;
    

    When creating the login vc I store my modal vc (which may be nil which is fine), dismiss it and present the login vc

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    LoginViewController *loginViewController =  [storyboard instantiateViewControllerWithIdentifier:@"LoginView"];
    
    self.navController = (UINavigationController *)self.window.rootViewController.presentedViewController;
    if (self.navController) {
        [self.navController dismissViewControllerAnimated:NO completion:nil];
    }
    [self.window.rootViewController presentViewController:loginViewController animated:NO completion:nil];
    

    And when the login is successfull I dismiss the login vc and restore the modal vc (if available)

    if (self.navController) {
        [self.window.rootViewController presentViewController:self.navController animated:NO completion:nil];
    }