Rizwan Sattar
Rizwan Sattar

Reputation: 1618

presentViewController:animated:NO briefly shows presenting controller in iOS 8. Alternatives?

It's typical during app startup to create your main UI structure, but during if user is not logged in during app launch, to immediately present a modal intro/login screen above the normal UI.

Normally it has been fine to present the modal UI using presentViewController:animated:NO, because the user would see: App Launch Image -> Login UI.

However, on iOS 8, it seems calling presentViewController with animated = NO still briefly shows the underlying view controller for a frame before presenting the view controller.

Example:

I don't want to present the login UI first, because when the user logged in I'd be presenting the main UI from the login UI, thus keeping the login UI around in the hierarchy indefinitely.

Is there another way I haven't considered? Could storyboards help me here?

Upvotes: 5

Views: 1894

Answers (3)

Daniel T.
Daniel T.

Reputation: 33967

I don't know what your exact usecase is, but in my app the user could be logged out at any moment regardless of what view controller (s)he happens to be in at the time. I need to then present the login screen and give the user a chance to log back in, and put the user right back where (s)he was if login was successful.

What all this means is that I can't make the login view controller the root and stack the other controllers on top of it, because I can't just pop them all off if the user gets logged out.

However, I can save the VC stack and swap out to the login screen, then swap back to the main VC stack when login is successful.

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var primaryViewController: UIViewController?
    var loginViewController: UIViewController?

    func userLoggedOut() {
        self.window?.rootViewController = loginViewController
    }

    func userLoggedIn() {
        self.window?.rootViewController = primaryViewController
    }

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // other setup code
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        loginViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as? UIViewController
        primaryViewController = self.window?.rootViewController

        if (!currentlyLoggedIn) {
            userLoggedOut()
        }
        return true
    }

Upvotes: 1

Anna Dickinson
Anna Dickinson

Reputation: 3347

I'm guessing the problem will go away if you use storyboards and don't programmaticly instantiate your initial or login view controllers. UIKit seems to work best when you just let it do its thing...

Here's how to conditionally bring up the login view controller using a storyboard:

https://stackoverflow.com/a/26657778/1442620

Upvotes: 1

jrturton
jrturton

Reputation: 119272

Personally I check for logged in status on application launch, and then either install the login view controller or the main root view controller as the window's root view controller.

When the user logs in or out, the window's root view controller is replaced. This can be animated as well. I find this approach quite clean.

Upvotes: 2

Related Questions