Search code examples
iosobjective-cuiviewcontrollerpasswordspresentviewcontroller

Control app snapshot when app comes back to foreground


I'm going to implement a specific ViewController which - popups each time my app comes in foreground, - requires an access password.

Since the app is already mature and a bit complex, I'd rather handle this password screen as a separate ViewController that appears on top of other VCs, invoked from AppDelegate by methods such as applicationDidBecomeActive:

    if (self.pwdVc==nil)
        self.pwdVc = [mainStoryboard instantiateViewControllerWithIdentifier:@"passwordScreen"];
    [self.window.rootViewController presentViewController:self.pwdVc animated:NO completion:nil];

The issue with this approach seems to be: when the app comes in foreground, the password ViewController is not already drawn on screen, and for a short lapse the real app screen is shown in clear.

Even if I trigger presenting the password ViewController in applicationDidEnterBackground, in advance, the actual screen redraw will always happen when the apps comes back in foreground, thus showing the app screen unwantedly.

May anyone please suggest the most proper method to have this password screen hide the underlying ViewControllers with no delay?

Methods with alpha settings switching from 0.0 to 1.0 also seem taking some time to show, and did not work up to now.

Thank you!


Solution

  • The solution came from this topic, and is based on putting an opaque "screen lock" view on top of any other view and control it by its hidden property in the proper AppDelegate methods!

    So:

    1. Add a view on top of any other view in Interface Builder, and initially set its view.hidden=NO in didFinishLaunchingWithOptions;
    2. Ensure to set view.hidden=NO in applicationWillResignActive, since this call will occur both when sending app to background and when invoking the multitasking screen;
    3. Place a button in the "screen lock" view, invoking a method which sets view.hidden=YES when password is correct.

    Optionally use layer.zPosition to adjust the order of visible views.

    Et voilà! Thank you all!