简体   繁体   中英

Delay applicationDidEnterBackground screen capture

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?

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 the applicationDidEnterBackground: method returns.

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...

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM