【问题标题】:Display a view or splash screen before applicationDidEnterBackground (to avoid active view screenshot)在 applicationDidEnterBackground 之前显示视图或启动屏幕(以避免活动视图屏幕截图)
【发布时间】:2013-11-16 13:19:03
【问题描述】:

我的应用中有机密信息,因此我想在应用即将移至后台时使用启动屏幕将其隐藏。

我确实在 iOS6 及更高版本上运行该应用程序。

我试图在applicationWillResignActive 中显示视图,但问题是即使用户滑动控制面板也会显示启动画面。我希望它仅在应用移至后台时显示。

我试图在applicationDidEnterBackground 中显示我的splashScreen,但它需要先截屏,因此在动画期间恢复时会显示信息。

这里是我想要的精神:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [_window addSubview:__splashController.view];
}

【问题讨论】:

  • AFAIK,您需要在applicationWillResignActive 中执行您的操作并撤消UIApplicationDelegate 方法中的相同操作applicationDidBecomeActive
  • 问题是,如果我确实在applicationWillResignActive 中显示我的启动画面,那么只要用户查看他的控制面板或双击主页按钮就会显示它...
  • Paypal iOS 应用程序做了类似的事情,当应用程序进入后台时,它们会模糊最后一个活动视图(以保护用户信息)。我建议您学习该应用程序或其他一些应用程序。编辑:我刚刚注意到,当控制面板打开时,paypal 不会模糊,所以我相信有一些方法,所以你想要实现的应该是可行的。将密切关注此线程。
  • 这有点像我想做的(因为我的应用程序还处理银行信息),但我不确定贝宝是否让我看到它的代码:/
  • @Andrea - 但他正在寻找的应该是可行的,因为许多其他金融(寻求安全性)应用程序,如PaypalBofA 都是这样做的。 (注意 - 在 iPad 上 - 控制中心、通知中心等部分覆盖了应用程序)。我认为解决方案并不难,但它只是没有点击我。让我们投票赞成这个问题,以在这里引起正确的注意力:)。另外@AncAinu - 如果尚未完成,您应该在实际设备(不仅仅是模拟器)上尝试您的解决方案。

标签: ios background ios7 screenshot uiapplicationdelegate


【解决方案1】:

我认为问题在于您正在 模拟器 中进行测试。在设备上,它应该可以正常工作。

我对此进行了测试,它确实有效。当应用进入后台时,添加带有初始图像的图像视图 -

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

当应用返回前台时 -

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

}

注意 - 在模拟器 (iOS 7.0) 上,当您按两次主页按钮 (Cmd + H) 进行检查时,不会显示添加的子视图,但在设备上它按预期工作(如 paypalBofA 应用程序)

编辑:(附加信息)

除了如上所述通过添加子视图/模糊来隐藏/替换敏感信息外,iOS 7 还允许您通过 ignoreSnapshotOnNextApplicationLaunchUIApplication 内的 ignoreSnapshotOnNextApplicationLaunch 忽略屏幕快照或 applicationWillResignActive 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);

另外,allowScreenShot 标志可以在 Restrictions Payload 中探索。

【讨论】:

  • 是的,那是我的闪电消失的那一天......确实它在真实设备上运行良好。
  • 此方法有效,除非正在播放视频。我可以隐藏正在播放的视频吗?
【解决方案2】:
@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

【讨论】:

  • 如果屏幕上显示某些系统警报,您会怎么做。在这种情况下,MySplashView 也会显示在屏幕上。我可以避免这种情况吗?
【解决方案3】:

需要编写如下代码:

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

这里删除imageview:

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

它正在工作并经过适当的测试。

【讨论】:

    【解决方案4】:

    有同样的问题,基本上我是使用applicationDidEnterBackground 在内容顶部显示一个 UIWindow,但在 iOS8 中它不像在 iOS7 中那样工作。

    我找到的解决方案是在applicationWillResignActive 中创建 UIWindow,但将其隐藏securityWindow.hidden = YES;然后在applicationDidEnterBackground 中,我要做的就是更改securityWindow.hidden = NO

    这似乎与 iOS7 在使用 NotificationCenter 或 ControlPanel 时在多任务处理时隐藏内容而不影响视图完全一样。

    【讨论】:

    • 这正是我所需要的。在 iOS7 到 iOS9 上测试。
    【解决方案5】:

    这为我解决了这个问题,抱歉,这是为 Xamarin.Forms 准备的,但您应该明白这一点。您需要在 xamarin 中调用 UIView.SnapshotView(true) 或在 iOS 上调用 UIView snapshotViewAfterScreenUpdates。在 iOS7 和 iOS8 上的 DidEnterBackground 中工作:

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

    【讨论】:

      【解决方案6】:

      不知道为什么,但这里描述的方法都不适合我。出于安全原因,我只是想遮住屏幕。所以,帮助的是来自 Apple 的技术问答:https://developer.apple.com/library/ios/qa/qa1838/_index.html

      我猜主要区别是使用 UIViewController?无论如何,以下代码在 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];
      }
      

      【讨论】:

      • 如果alertview正在显示,它不会被隐藏,如何在后台模式下隐藏alertview
      • 小心使用这个;如果您在当前窗口上显示了一个模态,并且 presentViewController 方法没有完成,那么当您返回前台时,您的模态可能会被关闭。
      【解决方案7】:

      Swift 3.0 Answer适合那些懒得翻译的人。

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

      【讨论】:

        【解决方案8】:

        我认为这将有助于 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()
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-04-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多