应用处于非活动状态时叠加图片

时间:2017-11-20 03:54:26

标签: ios objective-c

我正在使用这些代码

1)当应用程序处于非活动状态时覆盖图像(双击主页按钮两次)。

2)当应用程序处于活动状态时(重新打开应用程序)删除图像

在appdelegate.h文件中:

@property (nonatomic, strong) UIImageView *splashScreenImageView;

在appdelegate.m文件中:

- (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;
    }
}

问题:

然而, SOMETIME 当按下主页按钮两次时,iOS仍会在应用程序界面缓存敏感信息而不是iOS 11中的叠加图像。在iOS10中没有测试过。

更新

更改为此后问题仍然存在:

- (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];
}

4 个答案:

答案 0 :(得分:0)

我发现了一种棘手的方法,它适用于iOS 11或iOS 10。

在Appdelegate.m文件中:

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

在didFinishLaunchingWithOptions中添加此代码以设置图像和更新框架

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

实现此方法以获取最顶层的视图控制器

- (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];
}

现在在 applicationWillResignActive 方法中首先获取顶部viewController并将该视图上的splashScreenImageView设置为子视图

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

最后在 applicationDidBecomeActive 当app打开时首先删除叠加图片并打开应用

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

这个技巧会起作用。

答案 1 :(得分:0)

您的代码应该可以正常工作,

可能是您的应用在applicationWillResignActive调用时没有时间按时分配您的imageView 而且你每次都在重新创建对象。与[UIImageView alloc] initWithImage

所以我的建议是将此代码放在didFinishLaunching

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

只需在UIWindow上添加子视图,然后在applicationDidBecomeActive

时将其删除

同时将_splashScreenImageView带到前面!!

希望它可以解决您的问题

祝你好运

<强>更新

添加主队列

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

在主队列中删除

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

更新2

根据https://developer.apple.com/library/content/qa/qa1838/_index.html

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

  

准备应用程序快照   应用程序委托的applicationDidEnterBackground:方法返回后不久,系统会拍摄应用程序窗口的快照。类似地,当应用程序被唤醒以执行后台任务时,系统可以拍摄新的快照以反映任何相关的更改。例如,当唤醒应用程序以处理下载的项目时,系统会拍摄新的快照,以便反映由项目合并引起的任何更改。系统在多任务UI中使用这些快照图像来显示应用程序的状态。

     

如果在进入后台时对视图进行了更改,则可以调用主视图的snapshotViewAfterScreenUpdates:方法来强制渲染这些更改。在视图上调用setNeedsDisplay方法对快照无效,因为快照是在下一个绘制周期之前拍摄的,因此可以防止呈现任何更改。调用值为YES的snapshotViewAfterScreenUpdates:方法会强制立即更新快照机制使用的基础缓冲区。

尝试在Apple的演示

中显示临时视图控制器applicationDidEnterBackground

答案 2 :(得分:-1)

我修复了你的错误:

#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

答案 3 :(得分:-1)

双击应用程序时,执行以下两个简单步骤即可设置黑色图像,它位于最近的应用列表中。并在应用程序激活时删除黑色图像。

@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];
    }
}