Is there a way to delay the screen capture made by iOS when app is entering background? The reason is that I'm sometimes showing a view when the user goes to home screen I want this view removed so it doesn't show when app is resumed. The view in question is a SSHUDView
(source code here) which I call dismissAnimated:NO
in applicationWillResignActive
. This actually works in the simulator but not on real device (the SSHUDView
still shows when resuming). Anyone have a clue how to deal with this?
问题:
回答1:
If you have a look at the SSHUDView
implementation it uses a UIWindow
instance to display the content; it makes it's own UIWindow the key UIWindow
:
[_hudWindow makeKeyAndVisible];
Which is probably why it's so tricky to get rid of. You might try to do what SSHUDView
does after it dismisses itself to return focus to the main window:
[[[[UIApplication sharedApplication] windows] objectAtIndex:0] makeKeyWindow];
When the hud view dismissed itself it sends resignKeyWindow
to it's private _hudWindow
object, you could possibly try to get a handle on that before you return focus to the main window, like so:
[[[[UIApplication sharedApplication] windows] objectAtIndex:1] resignKeyWindow];
But it may cause unexpected problems because you're bypassing the SSHUDView
API...
回答2:
I think you should handle this in applicationDidEnterBackground:
.
According to Apple's documentation:
- Prepare to have their picture taken. When the
applicationDidEnterBackground:
method returns, the system takes a picture of your app’s user interface and uses the resulting image for transition animations. If any views in your interface contain sensitive information, you should hide or modify those views before theapplicationDidEnterBackground:
method returns.
回答3:
Could you possibly get the view controller displaying the SSHUDView to listen for UIApplicationWillResignActiveNotification
from [NSNotificationCenter defaultCenter]
and hide it that way? Seems a little hacky, so it may not work. Just a thought.
回答4:
This worked for me, both simulator and real hardware. In applicationDidEnterBackground:
you can create a temporary view controller with a black background and present it modally over the "topmost" view controller (in case there's already a view controller being presented modally). Simply remove it when the app comes back in applicationWillEnterForeground:
#import "AppDelegate.h"
@interface AppDelegate ()
@property (strong, nonatomic) UIViewController *veilController;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController.view.backgroundColor = [UIColor redColor];
[self.window makeKeyAndVisible];
UIViewController *vc0 = [[UIViewController alloc] initWithNibName:nil bundle:nil];
vc0.view.backgroundColor = [UIColor blueColor];
[self.window.rootViewController presentViewController:vc0 animated:NO completion:nil];
UIViewController *vc1 = [[UIViewController alloc] initWithNibName:nil bundle:nil];
vc1.view.backgroundColor = [UIColor purpleColor];
[vc0 presentViewController:vc1 animated:NO completion:nil];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
self.veilController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
self.veilController.view.backgroundColor = [UIColor blackColor];
UIViewController *tvc = self.window.rootViewController;
while (tvc) {
if (tvc.presentedViewController) {
tvc = tvc.presentedViewController;
} else {
[tvc presentViewController:self.veilController animated:NO completion:nil];
tvc = nil;
}
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self.veilController dismissViewControllerAnimated:NO completion:nil];
self.veilController = nil;
}
@end