Показывать экран представления или всплеска перед applicationDidEnterBackground (чтобы избежать скриншота активного просмотра)
У меня есть конфиденциальная информация в моем приложении, поэтому я хотел бы скрыть их с помощью заставки, когда приложение будет перемещено в фоновый режим.
Я запускаю приложение на iOS6 и далее.
Я попытался отобразить представление в applicationWillResignActive
, но проблема в том, что он отображает экран заставки, даже если пользовательская панель управления салфеткой, например. Я хочу, чтобы он показывался только тогда, когда приложение перемещено на задний план.
Я попытался отобразить свой splashScreen в applicationDidEnterBackground
, но он берет screenShot, прежде чем информация будет отображаться при восстановлении во время анимации.
Вот дух того, что я хочу:
- (void)applicationDidEnterBackground:(UIApplication *)application {
[_window addSubview:__splashController.view];
}
Ответы
Ответ 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 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), но на устройстве оно работает как ожидалось (например, paypal
, BofA
apps)
EDIT: (Дополнительная информация)
В дополнение к скрытию/замене конфиденциальной информации путем добавления subview/blur, как объяснялось выше, iOS 7 предоставляет вам возможность игнорировать снимок экрана через ignoreSnapshotOnNextApplicationLaunch
UIApplication
внутри 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
можно изучить в "Полезная нагрузка ограничений" .
Ответ 2
Имела ту же проблему, по сути, я использовал applicationDidEnterBackground
, чтобы показать UIWindow поверх содержимого, но в iOS8 он не работал так, как в iOS7.
Решение, которое я нашел, это создать UIWindow в applicationWillResignActive
, но сделать его скрытым securityWindow.hidden = YES
; а затем в applicationDidEnterBackground
все, что я сделал бы, это изменить securityWindow.hidden = NO
.
Кажется, что это работает точно так же, как iOS7, скрывая содержимое при многозадачности, не влияя на представление при использовании NotificationCenter или ControlPanel.
Ответ 3
Swift 3.0 Отвечать для тех, кто ленив для перевода.
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()
}
}
Ответ 4
Не знаю почему, но ни один из описанных здесь методов не работал. Я просто пытался покрыть экран по соображениям безопасности. Итак, что помогло Техническое Q & A от 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];
}
Ответ 5
Необходимо написать код следующим образом:
-(void)applicationWillResignActive:(UIApplication *)application
{
imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
[imageView setImage:[UIImage imageNamed:@"Portrait(768x1024).png"]];
[self.window addSubview:imageView];
}
Здесь, чтобы удалить изображение:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(imageView != nil) {
[imageView removeFromSuperview];
imageView = nil;
}
}
Он работает и проверен правильно.
Ответ 6
@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
Ответ 7
Это исправило это для меня, извините, это для Xamarin.Forms, но вы должны получить эту идею. Вам нужно вызвать UIView.SnapshotView(true) в xamarin или UIView snapshotViewAfterScreenUpdates
на iOS. Работает в DidEnterBackground на iOS7 и iOS8:
public override void DidEnterBackground(UIApplication uiApplication)
{
App.Current.MainPage = new DefaultPage();
**UIApplication.SharedApplication.KeyWindow.SnapshotView(true);**
base.DidEnterBackground(uiApplication);
}
Ответ 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()
}
}