Display a view or splash screen before applicationDidEnterBackground (to avoid active view screenshot)

两盒软妹~` 提交于 2019-11-26 22:08:12

I think the problem is that you are testing in simulator. On device, it should work fine.

I tested this and it worked. Add an imageview with your splash image when app enters in background -

- (void)applicationDidEnterBackground:(UIApplication *)application
{

        UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.window.bounds];

        imageView.tag = 101;    // Give some decent tagvalue or keep a reference of imageView in self
    //    imageView.backgroundColor = [UIColor redColor];
        [imageView setImage:[UIImage imageNamed:@"Default.png"]];   // assuming Default.png is your splash image's name

        [UIApplication.sharedApplication.keyWindow.subviews.lastObject addSubview:imageView];
}

And when app comes back in foreground -

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    UIImageView *imageView = (UIImageView *)[UIApplication.sharedApplication.keyWindow.subviews.lastObject viewWithTag:101];   // search by the same tag value
    [imageView removeFromSuperview];

}

NOTE - On simulator (iOS 7.0), the added subview is not show when you check by pressing home button twice (Cmd + H), but on device it works as expected (like paypal, BofA apps)

EDIT: (Additional info)

In addition to obscuring/replacing sensitive information by adding subview / blur as explained above, iOS 7 provides you ability to ignore the screen snapshot via ignoreSnapshotOnNextApplicationLaunch of UIApplication inside applicationWillResignActive or applicationDidEnterBackground.

UIApplication.h

// Indicate the application should not use the snapshot on next launch, even if there is a valid state restoration archive.
// This should only be called from methods invoked from State Preservation, else it is ignored.
- (void)ignoreSnapshotOnNextApplicationLaunch NS_AVAILABLE_IOS(7_0);

Also, allowScreenShot flag can be explored in Restrictions Payload.

Swift 3.0 Answer for those who are to lazy to translate.

func applicationDidEnterBackground(_ application: UIApplication) {

    let imageView = UIImageView(frame: self.window!.bounds)
    imageView.tag = 101
    imageView.image = ...

    UIApplication.shared.keyWindow?.subviews.last?.addSubview(imageView)
 }

func applicationWillEnterForeground(_ application: UIApplication) {

    if let imageView : UIImageView = UIApplication.shared.keyWindow?.subviews.last?.viewWithTag(101) as? UIImageView {
        imageView.removeFromSuperview()
    }

}

Had the same issue, essentially I was using applicationDidEnterBackground to show a UIWindow on top of the content, but in iOS8 it didn't work as it did in iOS7.

The solution I found was to create the UIWindow in applicationWillResignActive but make it hidden securityWindow.hidden = YES; and then in applicationDidEnterBackground all I would do would be to change securityWindow.hidden = NO.

This seems to work exactly as iOS7 obscuring the content when multi tasking without affecting the view when using NotificationCenter or ControlPanel.

Don't know why, but none of the methods described here worked for me. I was simply trying to cover the screen for security reasons. So, what helped was a Technical Q&A from Apple: https://developer.apple.com/library/ios/qa/qa1838/_index.html

I guess the main difference is using a UIViewController? Anyways, the following code works perfectly for me on IOS 9.1:

- (void)applicationDidEnterBackground:(UIApplication *)application
{     
    UIViewController *blankViewController = [UIViewController new];
    blankViewController.view.backgroundColor = [UIColor blackColor];

    [self.window.rootViewController presentViewController:blankViewController animated:NO completion:NULL];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [self.window.rootViewController dismissViewControllerAnimated:NO completion:NO];
}
Deepak Kumar

Need to write the code as follows:

-(void)applicationWillResignActive:(UIApplication *)application
{
    imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
    [imageView setImage:[UIImage imageNamed:@"Portrait(768x1024).png"]];
    [self.window addSubview:imageView];
}

Here to remove the imageview:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(imageView != nil) {
        [imageView removeFromSuperview];
        imageView = nil;
    }
}

It is working and properly tested.

@interface MyAppDelegate ()
@property (strong, nonatomic) MySplashView *splashView;
@end
@implementation MyAppDelegate
- (void)applicationWillResignActive:(UIApplication *)application {
    // hide keyboard and show a splash view
    [self.window endEditing:YES];
    MySplashView *splashView = [[MySplashView alloc] initWithFrame:self.window.bounds];
    [self.window addSubview:splashView];
    self.splashView = splashView;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // remove the splash view
    if (self.splashView) {
        [self.splashView removeFromSuperview];
        self.splashView = nil;
    }
}
@end

This fixed it for me, sorry this is for Xamarin.Forms but you should get the idea. You need to call UIView.SnapshotView(true) in xamarin or UIView snapshotViewAfterScreenUpdates on iOS. Works in DidEnterBackground on iOS7, and iOS8:

public override void DidEnterBackground(UIApplication uiApplication)
{
    App.Current.MainPage = new DefaultPage();
    **UIApplication.SharedApplication.KeyWindow.SnapshotView(true);**
    base.DidEnterBackground(uiApplication);
}

I think this will help for Swift 3.0

func applicationWillResignActive(_ application: UIApplication) {

        let imageView = UIImageView(frame: self.window!.bounds)
        imageView.tag = 101
        imageView.backgroundColor = UIColor.white
        imageView.contentMode = .center
        imageView.image = #image#
        UIApplication.shared.keyWindow?.subviews.last?.addSubview(imageView)

    }

func applicationWillEnterForeground(_ application: UIApplication) {
        ReachabilityManager.shared.stopMonitoring()
        if let imageView : UIImageView = UIApplication.shared.keyWindow?.subviews.last?.viewWithTag(101) as? UIImageView {
            imageView.removeFromSuperview()
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!