I want to lock users out of my app after a period of being in the background. I'm catching this in the the AppDelegate's applicationWillEnterForeground
(and comparing to time stored in applicationWillResignActive
). If less than the timeout period no action takes place. If more than the timeout period I call:
[_navigationController popToRootViewControllerAnimated:NO];
which brings the user back to the root view.
It works perfectly fine with one visual interruption. The prior view (that which the user was viewing when the application went inactive) appears very briefly before popping to root. In testing it seems the view reappears prior to applicationWillEnterForeground
being called.
The only thought I've had is to hide everything before going inactive, such as by obscuring the view with a filled rectangle. This smells like a dirty hack to me, so I'm thinking there's a better way.
I'm also open to different ways to reach the same end result. Thank you!
I've solved this by making the view invisible. In applicationWillResignActive I have _navigationController.view.alpha=0;, and I've placed _navigationController.view.alpha=100; in applicationWillEnterForeground after (if necessary) popping to the login view. Easier than popping and restoring views (which in this case are pretty heavy).
@TheBlack points out the hidden property, which is probably slightly easier on the device. I'm leaving alpha in because A) it's fun debugging with a 50% alpha view, and B) I just like alpha's. But unless you're an alpha fan like me, hidden might be a little better.
From the docs: Strategies for Handling App State Transitions
Prepare for the App Snapshot
Shortly after an app delegate’s applicationDidEnterBackground: method returns, the system takes a snapshot of the app’s windows. Similarly, when an app is woken up to perform background tasks, the system may take a new snapshot to reflect any relevant changes. For example, when an app is woken to process downloaded items, the system takes a new snapshot so that can reflect any changes caused by the incorporation of the items. The system uses these snapshot images in the multitasking UI to show the state of your app.
If you make changes to your views upon entering the background, you can call the snapshotViewAfterScreenUpdates: method of your main view to force those changes to be rendered. Calling the setNeedsDisplay method on a view is ineffective for snapshots because the snapshot is taken before the next drawing cycle, thus preventing any changes from being rendered. Calling the snapshotViewAfterScreenUpdates: method with a value of YES forces an immediate update to the underlying buffers that the snapshot machinery uses.