В Підготовка інтерфейсу для роботи у фоновому режимі , Apple говорить:
Підготуйте інтерфейс користувача до знімка програми
Через деякий час після того, як ваша програма перейде на задній план і ваш метод делегації повернеться, UIKit робить знімок поточного користувальницького інтерфейсу вашої програми. Система відображає отримане зображення в перемикачі програм. Він також відображає зображення тимчасово, коли ваш додаток повертається на перший план.
Інтерфейс вашого додатка не повинен містити конфіденційну інформацію користувачів, наприклад паролі чи номери кредитних карт. Якщо ваш інтерфейс містить таку інформацію, видаліть її зі своїх поглядів під час виходу на задній план. Крім того, відхиліть сповіщення, тимчасові інтерфейси та контролери перегляду системи, які затемнюють вміст вашої програми. Знімок відображає інтерфейс вашої програми та має бути розпізнаваним для користувачів. Коли ваша програма повернеться на перший план, ви можете відновити дані та представлення даних, якщо це доречно.
Див. Технічні питання QA1838: Запобігання появі чутливої інформації у перемикачі завдань
На додаток до затемнення / заміни конфіденційної інформації, ви також можете сказати iOS 7 не робити знімок екрана ignoreSnapshotOnNextApplicationLaunch
, в документації якого написано:
Якщо ви вважаєте, що знімок не може правильно відображати користувальницький інтерфейс вашого додатка, коли програма перезапущена, ви можете зателефонувати, ignoreSnapshotOnNextApplicationLaunch
щоб запобігти зняттю цього знімку.
Сказавши це, виявляється, що знімок екрана все ще зроблений, і тому я подав звіт про помилку. Але слід перевірити далі і побачити, чи допоможе використання цього параметра.
Якщо це був корпоративний додаток, ви також можете вивчити відповідне налаштування, 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
, ніж рекомендується applicationDidEnterBackground
, тому що, як зазначали інші, останній не викликається при подвійному натисканні на кнопку додому під час роботи програми.
Я б хотів, щоб я міг використовувати сповіщення для обробки всього цього, а не шаблон делегатного протоколу, але в умовах мого обмеженого тестування повідомлення не обробляються вчасно достатньо, але вищевказаний зразок справно працює.