Image overlay when the application is inactive

I use this code for

1) overlay the image when the application is inactive (double-click the "Home" button twice).

2) Delete the image when the application is active (open the application)

In the appdelegate.h file:

@property (nonatomic, strong) UIImageView *splashScreenImageView; 

In the appdelegate.m file:

 - (void)applicationWillResignActive:(UIApplication *)application { UIImage *splashScreenImage = [UIImage imageNamed:@"BackgroundScreenCaching"]; _splashScreenImageView = [[UIImageView alloc] initWithImage:splashScreenImage]; [self.window addSubview:_splashScreenImageView]; } - (void)applicationDidBecomeActive:(UIApplication *)application { if(_splashScreenImageView != nil) { [_splashScreenImageView removeFromSuperview]; _splashScreenImageView = nil; } } 

Problem:

However, SOMETIME , while pressing the iOS home button, still caches the application’s screen with confidential information instead of the overlay image in iOS 11. Did not test the problem in iOS10.

Update

The problem persists after the change:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { BOOL result = [super application:application didFinishLaunchingWithOptions:launchOptions]; ... UIImage *splashScreenImage = [UIImage imageNamed:@"BackgroundScreenCaching"]; _splashScreenImageView = [[UIImageView alloc] initWithImage:splashScreenImage]; [_splashScreenImageView setFrame:self.window.bounds]; return result; } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. if(_splashScreenImageView != nil) { [_splashScreenImageView removeFromSuperview]; } } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. [self.window addSubview:_splashScreenImageView]; } 
+5
source share
4 answers

I found a difficult way and it works with iOS 11 or iOS 10.

In the Appdelegate.m file:

  @implementation AppDelegate { UIImageView *splashScreenImageView; UIViewController *viewController; } 

Add this code to doneFinishLaunchingWithOptions to set the image frame and updates

  splashScreenImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)]; splashScreenImageView.image = [UIImage imageNamed:@"BackgroundScreenCaching"]; 

Implement this method to get the top view controller

 - (UIViewController *)topViewController{ return [self topViewController:[UIApplicationsharedApplication].keyWindow.rootViewController]; } - (UIViewController *)topViewController:(UIViewController *)rootViewController { if (rootViewController.presentedViewController == nil) { return rootViewController; } if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) { UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController; UIViewController *lastViewController = [[navigationController viewControllers] lastObject]; return [self topViewController:lastViewController]; } UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController; return [self topViewController:presentedViewController]; } 

Now in the applicationWillResignActive application, first get the top viewController and set splashScreenImageView in this view as a subview

 - (void)applicationWillResignActive:(UIApplication *)application { viewController = [self topViewController]; [viewController.view addSubview:splashScreenImageView]; } 

Finally, in applicationDidBecomeActive , when the application is open, first remove the overlay image and open the application

 - (void)applicationDidBecomeActive:(UIApplication *)application { [splashScreenImageView removeFromSuperview]; } 

These tricks will work.

0
source

Your code should work fine,

Perhaps your application did not have time to highlight your image at the point in time when applicationWillResignActive called and you recreate the object each time. with [UIImageView alloc] initWithImage

So my suggestion puts this code in didFinishLaunching

 UIImage *splashScreenImage = [UIImage imageNamed:@"BackgroundScreenCaching"]; _splashScreenImageView = [[UIImageView alloc] initWithImage:splashScreenImage]; 

and just add subview on UIWindow and delete it when applicationDidBecomeActive

Also add _splashScreenImageView to the top !!

Hope this can solve your problem.

Luck

UPDATE

to add to the main queue

 dispatch_async(dispatch_get_main_queue(), ^{ [self.window addSubview:_splashScreenImageView]; [self.window bringSubviewToFront:_splashScreenImageView]; }); 

to delete in the main queue

 dispatch_async(dispatch_get_main_queue(), ^{ [_splashScreenImageView removeFromSuperview]; }); 

UPDATE 2

according to https://developer.apple.com/library/content/qa/qa1838/_index.html

and https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html

Prepare for the application snapshot Shortly after the application delegates the applicationDidEnterBackground: the method returns the system takes a snapshot of the application windows. Similarly, when an application wakes up to perform background tasks, the system can take a new snapshot to reflect any relevant changes. For example, when an application wakes up to process loaded elements, the system takes a new snapshot so that it can reflect any changes caused by the inclusion of elements. The system uses these snapshots in the multitasking interface to show the status of your application.

If you make changes to your views when entering the background, you can call the snapshotViewAfterScreenUpdates: method of your main view to force these changes to be visualized. Calling the setNeedsDisplay method in a view is ineffective for snapshots because the snapshot is taken until the next drawing cycle, which prevents any changes from being rendered. Calling the snapshotViewAfterScreenUpdates: method with a value of YES forces the base buffers used by the snapshot engine to be updated immediately.

Try introducing the applicationDidEnterBackground temporary view manager as you did in the Apple demo

0
source

I am correcting your error as follows:

 #import "AppDelegate.h" @interface AppDelegate () { UIImageView *test ; } @end @implementation AppDelegate - (void)applicationDidEnterBackground:(UIApplication *)application { UIImage *splashScreenImage = [UIImage imageNamed:@"ic_target_black"]; test = [[UIImageView alloc] initWithImage:splashScreenImage]; [self.window addSubview:test]; } - (void)applicationDidBecomeActive:(UIApplication *)application { if (test) { [test removeFromSuperview]; } } @end 
-1
source

Take two simple steps to set your black image when double-clicking an application and it is in the list of recent applications. And remove the black image when the application becomes active.

 @interface AppDelegate (){ UIImageView *test ; } - (void)applicationWillResignActive:(UIApplication *)application { UIImage *splashScreenImage = [UIImage imageNamed:@"ss.png"]; test = [[UIImageView alloc] initWithImage:splashScreenImage]; [self.window addSubview:test]; } - (void)applicationDidBecomeActive:(UIApplication *)application { if (test) { [test removeFromSuperview]; } } 
-1
source

Source: https://habr.com/ru/post/1273518/


All Articles