在iOS 7多任务切换器中控制屏幕截图
我一直在试图find有关iOS 7中新的多任务切换器的信息,尤其是当应用程序进入hibernate状态时操作系统所采用的屏幕截图。
有没有办法彻底closures这个function或截图? 或者我可以从切换台完全隐藏应用程序吗? 该应用程序需要在后台运行,但我们不想显示应用程序的任何截图。
屏幕截图可能是一种安全风险,可以考虑在银行应用程序中,您的卡号或帐户摘要可供任何双击设备上主屏幕button的用户使用。
任何人有任何洞察到这个? 谢谢。
在iOS应用程序编程指南中 ,苹果公司表示:
在移至背景之前,从视图中移除敏感信息。
当应用程序转换到后台时,系统会拍摄应用程序主窗口的快照,然后在将应用程序切换回前台时,该窗口会短暂显示。 在从
applicationDidEnterBackground:
方法返回之前,您应该隐藏或遮掩可能作为快照一部分捕获的密码和其他敏感个人信息。
除了遮挡/replace敏感信息之外,您还可能想让iOS 7不通过ignoreSnapshotOnNextApplicationLaunch
获取屏幕快照。 根据这个方法的文档 :
如果您觉得快照在重新启动应用程序时无法正确反映应用程序的用户界面,则可以调用[
ignoreSnapshotOnNextApplicationLaunch
]以防止拍摄快照图像。
话虽如此,看起来屏幕截图仍然被采用,因此我提交了一个错误报告。 但是你应该进一步testing,看看使用这个设置是否有帮助。
如果这是一个企业应用程序,那么您可能还需要查看Configuration Profile Reference的Restrictions Payload部分中列出的allowScreenShot
的相应设置。
这是一个实现我所需要的实现。 您可以显示自己的UIImageView
,或者您可以使用委托协议模式来隐藏机密信息:
// SecureDelegate.h #import <Foundation/Foundation.h> @protocol SecureDelegate <NSObject> - (void)hide:(id)object; - (void)show:(id)object; @end
然后,我给了我的应用程序代表一个属性:
@property (weak, nonatomic) id<SecureDelegate> secureDelegate;
我的视图控制器设置它:
- (void)viewDidLoad { [super viewDidLoad]; AppDelegate *delegate = [[UIApplication sharedApplication] delegate]; delegate.secureDelegate = self; }
视图控制器显然实现了这个协议:
- (void)hide:(id)object { self.passwordLabel.alpha = 0.0; } - (void)show:(id)object { self.passwordLabel.alpha = 1.0; }
最后,我的应用程序委托使用这个协议和属性:
- (void)applicationWillResignActive:(UIApplication *)application { [application ignoreSnapshotOnNextApplicationLaunch]; // this doesn't appear to work, whether called here or `didFinishLaunchingWithOptions`, but seems prudent to include it [self.secureDelegate hide:@"applicationWillResignActive:"]; // you don't need to pass the "object", but it was useful during my testing... } - (void)applicationDidBecomeActive:(UIApplication *)application { [self.secureDelegate show:@"applicationDidBecomeActive:"]; }
请注意,我正在使用applicationWillResignActive
而不是build议的applicationDidEnterBackground
,因为正如其他人指出的,当应用程序运行时双击homebutton时,不会调用后者。
我希望我可以使用通知来处理所有这些,而不是委托协议模式,但是在我的有限testing中,通知没有及时处理,但上面的模式工作正常。
这是我为我的应用程序工作的解决scheme:
正如Tommy所说:你可以使用applicationWillResignActive。 我所做的是用我的SplashImage制作一个UIImageView,并将其作为子视图添加到我的主窗口中 –
(void)applicationWillResignActive:(UIApplication *)application { imageView = [[UIImageView alloc]initWithFrame:[self.window frame]]; [imageView setImage:[UIImage imageNamed:@"Portrait(768x1024).png"]]; [self.window addSubview:imageView]; }
我使用这种方法,而不是applicationDidEnterBackground,因为如果您双击主页button,applicationDidEnterBackground将不会被触发,并将applicationWillResignActive。 我听到有人说,虽然在其他情况下也可以触发,所以我现在还在testing,看看是否有问题,但没有到目前为止! ;)
这里删除imageview:
- (void)applicationDidBecomeActive:(UIApplication *)application { if(imageView != nil) { [imageView removeFromSuperview]; imageView = nil; } }
希望这可以帮助!
旁注:我在模拟器和真实设备上testing了它:它不会在模拟器上显示,但它在真实设备上显示!
这种快速简单的方法将在iOS7或更高版本的应用程序切换器中在应用程序图标上方产生黑色快照。
首先,将应用程序的关键窗口(通常在应用程序中的AppDelegate.m中设置:didFinishLaunchingWithOptions),并在应用程序即将移到后台时隐藏它:
- (void)applicationWillResignActive:(UIApplication *)application { if(isIOS7Or8) { self.window.hidden = YES; } }
然后,当您的应用再次处于活动状态时,取消隐藏应用的关键窗口:
- (void)applicationDidBecomeActive:(UIApplication *)application { if(isIOS7Or8) { self.window.hidden = NO; } }
此时,请查看应用切换器,确认您在应用图标上方看到黑色快照。 我注意到,如果您在将应用程序移动到后台后立即启动应用程序切换器,则可能会有5秒钟的延迟,您会看到应用程序的快照(您要隐藏的应用程序),之后它转换为全黑的快照。 我不确定拖延到底是怎么回事 如果有人有任何build议,请join。
如果你想在切换台中使用黑色以外的颜色,你可以通过添加一个你喜欢的背景颜色的子视图来做这样的事情:
- (void)applicationWillResignActive:(UIApplication *)application { if(isIOS7Or8) { UIView *colorView = [[[UIView alloc] initWithFrame:self.window.frame] autorelease]; colorView.tag = 9999; colorView.backgroundColor = [UIColor purpleColor]; [self.window addSubview:colorView]; [self.window bringSubviewToFront:colorView]; } }
然后,当您的应用程序再次变为活动状态时移除此颜色子视图:
- (void)applicationDidBecomeActive:(UIApplication *)application { if(isIOS7Or8) { UIView *colorView = [self.window viewWithTag:9999]; [colorView removeFromSuperview]; } }
我使用了以下解决scheme:当应用程序将要辞职时,我将appWindow快照视为View,并为其添加模糊处理。 然后我将这个视图添加到应用程序窗口
如何做到这一点:
-
在appDelegate之前执行添加行:
static const int kNVSBlurViewTag = 198490;//or wherever number you like
-
添加这个方法:
- (void)nvs_blurPresentedView { if ([self.window viewWithTag:kNVSBlurViewTag]){ return; } [self.window addSubview:[self p_blurView]]; } - (void)nvs_unblurPresentedView { [[self.window viewWithTag:kNVSBlurViewTag] removeFromSuperview]; } #pragma mark - Private - (UIView *)p_blurView { UIView *snapshot = [self.window snapshotViewAfterScreenUpdates:NO]; UIView *blurView = nil; if ([UIVisualEffectView class]){ UIVisualEffectView *aView = [[UIVisualEffectView alloc]initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]]; blurView = aView; blurView.frame = snapshot.bounds; [snapshot addSubview:aView]; } else { UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:snapshot.bounds]; toolBar.barStyle = UIBarStyleBlackTranslucent; [snapshot addSubview:toolBar]; } snapshot.tag = kNVSBlurViewTag; return snapshot; }
-
让你的appDelegate实现如下:
- (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. //... //your code //... [self nvs_blurPresentedView]; } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. //... //your code //... [self nvs_unblurPresentedView]; }
我在Swift和Objective C中创build了示例项目。 这两个项目在以下方面进行了以下操
– 应用程序:didResignActive – 创build快照,模糊并添加到应用程序窗口
-application:willBecomeActive模糊视图正在从窗口中删除。
如何使用:
对象C
-
将
AppDelegate+NVSBlurAppScreen
.h和.m文件添加到您的项目中 -
在你的-applicationWillResignActive:方法中添加下面一行:
[self nvs_blurPresentedView];
-
在你的-applicationDidEnterBackground:方法中添加下面一行:
[self nvs_unblurPresentedView];
迅速
-
将AppDelegateExtention.swift文件添加到您的项目
-
在你的applicationWillResignActive函数中添加下面一行:
blurPresentedView()
-
在你的applicationDidBecomeActive函数中添加下面一行:
unblurPresentedView()
如果只使用[self.window addSubview:imageView];
在applicationWillResignActive
函数中,这个imageView不会覆盖UIAlertView,UIActionSheet或MFMailComposeViewController …
最好的解决办法是
- (void)applicationWillResignActive:(UIApplication *)application { UIWindow *mainWindow = [[[UIApplication sharedApplication] windows] lastObject]; [mainWindow addSubview:imageView]; }
提供我自己的解决scheme作为“答案”,虽然这个解决scheme是非常不可靠的。 有时候我会得到一个黑屏作为屏幕截图,有时候是XIB,有时候是应用程序本身的屏幕截图。 根据设备和/或如果我在模拟器中运行此。
请注意,我无法提供此解决scheme的任何代码,因为这里有很多特定于应用程序的细节。 但是这应该解释我的解决scheme的基本要点。
在AppDelegate.m下applicationWillResignActive我检查我们是否运行iOS7,如果我们加载一个新的视图,与中间的应用程序标识是空的。 一旦applicationDidBecomeActive被调用,我重新启动我的旧视图,这将被重置 – 但这适用于我正在开发的应用程序的types。
您可以使用激活器configuration双击主页button启动多任务,并禁用默认双击主页button和启动多任务窗口。 此方法可用于将屏幕截图更改为应用程序的默认图像。 这适用于具有默认密码保护function的应用程序。
Xamarin.iOS
改编自https://stackoverflow.com/a/20040270/7561
我只想显示我的启animation面,而不是只显示一种颜色。
public override void DidEnterBackground(UIApplication application) { //to add the background image in place of 'active' image var backgroundImage = new UIImageView(); backgroundImage.Tag = 1234; backgroundImage.Image = UIImage.FromBundle("Background"); backgroundImage.Frame = this.window.Frame; this.window.AddSubview(backgroundImage); this.window.BringSubviewToFront(backgroundImage); } public override void WillEnterForeground(UIApplication application) { //remove 'background' image var backgroundView = this.window.ViewWithTag(1234); if(null != backgroundView) backgroundView.RemoveFromSuperview(); }