アプリに機密情報があるので、アプリをバックグラウンドに移動しようとしているときに、スプラッシュスクリーンでそれらを非表示にしたいと思います。
私はiOS6以降でアプリを実行します。
ビューをapplicationWillResignActive
で表示しようとしましたが、問題は、たとえばユーザーがコントロールパネルをスワイプしてもスプラッシュスクリーンが表示されることです。アプリがバックグラウンドに移動したときにのみ表示されるようにします。
applicationDidEnterBackground
にsplashScreenを表示しようとしましたが、アニメーションの復元時に情報が表示される前にscreenShotが必要です。
ここに私が欲しいものの精神:
- (void)applicationDidEnterBackground:(UIApplication *)application {
[_window addSubview:__splashController.view];
}
問題はあなたがsimulatorでテストしていることだと思います。デバイスでは、正常に動作するはずです。
私はこれをテストし、それはうまくいきました。アプリがバックグラウンドに入ったときにスプラッシュ画像を含む画像ビューを追加します-
- (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)では、ホームボタンを2回(Cmd + H)押してチェックすると、追加されたサブビューは表示されませんが、デバイスでは期待どおりに機能します(Paypal
、BofA
アプリなど)。
編集:(追加情報)
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
フラグは Restrictions Payload で確認できます。
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()
}
}
同じ問題があり、本質的にapplicationDidEnterBackground
を使用してコンテンツの上にUIWindowを表示していましたが、iOS8ではiOS7のように機能しませんでした。
私が見つけた解決策は、applicationWillResignActive
にUIWindowを作成することですが、それを非表示にするsecurityWindow.hidden = YES
;そしてapplicationDidEnterBackground
では、securityWindow.hidden = NO
を変更するだけです。
これは、NotificationCenterまたはControlPanelを使用するときにビューに影響を与えることなく、マルチタスク時にコンテンツを覆い隠すiOS7とまったく同じように機能するようです。
理由はわかりませんが、ここで説明する方法はどれもうまくいきませんでした。セキュリティ上の理由から、画面を隠そうとしただけです。だから、助けになったのはアップルからの技術的なQ&Aでした: 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];
}
次のようにコードを記述する必要があります。
-(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;
}
}
動作しており、適切にテストされています。
@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
これで解決しました。申し訳ありませんが、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);
}
これは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()
}
}