İOS 7 çoklu görev değiştiricisindeki ekran görüntüsünü kontrol etme


98

İOS 7'deki yeni çoklu görev değiştirici ve özellikle uygulama hazırda bekletme moduna geçerken işletim sisteminin aldığı ekran görüntüsü ile ilgili bazı bilgiler bulmaya çalışıyorum.

görüntü açıklamasını buraya girin

Bu özelliği veya ekran görüntüsünü tamamen kapatmanın bir yolu var mı? Veya uygulamayı değiştiriciden tamamen gizleyebilir miyim? Uygulamanın arka planda çalışması gerekiyor, ancak uygulamadan herhangi bir ekran görüntüsü göstermek istemiyoruz.

Ekran görüntüsü potansiyel olarak bir güvenlik riskidir, kart numaranızın veya hesap özetinizin cihazdaki ana sayfa düğmesine çift tıklayan herkes tarafından görülebileceği bankacılık uygulamaları satırlarını düşünün.

Bu konuda herhangi bir bilgisi olan var mı? Teşekkürler.


1
Mevcut çözümüm, uygulama hazırda bekletme moduna girdiğinde uygulama logosuyla boş bir görünüm yüklemek ve uygulama geri döndüğünde onu kaldırmaktır, ancak bu çözümün yönetilmesi zor ve zarif bir çözümden ziyade bir hack gibi görünüyor. Ayrıca, bu çözüm cihaza vb. Bağlı olarak zaman zaman başarısız oluyor. Yani gerçekten kullanılabilir bir çözüm değil.
Tommie

Yanıtlar:


101

In arka planda çalışmasına Kişisel UI Hazırlama Apple diyor ki:

Kullanıcı Arayüzünüzü Uygulama Anlık Görüntüsü için Hazırlayın

Uygulamanız arka plana girdikten ve temsilci yönteminiz döndükten bir noktada, UIKit, uygulamanızın mevcut kullanıcı arayüzünün anlık görüntüsünü alır. Sistem, ortaya çıkan görüntüyü uygulama değiştiricide görüntüler. Ayrıca, uygulamanızı ön plana getirirken resmi geçici olarak görüntüler.

Uygulamanızın kullanıcı arayüzü, şifreler veya kredi kartı numaraları gibi hassas kullanıcı bilgileri içermemelidir. Arayüzünüz bu tür bilgiler içeriyorsa, arka plana girerken bu bilgileri görünümlerinizden kaldırın. Ayrıca, uygulamanızın içeriğini gizleyen uyarıları, geçici arayüzleri ve sistem görünümü denetleyicilerini kapatın. Anlık görüntü, uygulamanızın arayüzünü temsil eder ve kullanıcılar tarafından tanınabilmelidir. Uygulamanız ön plana döndüğünde, verileri ve görünümleri uygun şekilde geri yükleyebilirsiniz.

Bkz. Teknik Soru ve Cevap QA1838: Hassas Bilgilerin Görev Değiştiricide Görünmesini Önleme

Hassas bilgileri gizlemeye / değiştirmeye ek olarak, iOS 7'ye ignoreSnapshotOnNextApplicationLaunch, dokümantasyonunda şunlar yazan ekran anlık görüntüsünü almamasını söylemek isteyebilirsiniz :

Uygulamanız yeniden başlatıldığında ignoreSnapshotOnNextApplicationLaunchanlık görüntünün , uygulamanızın kullanıcı arayüzünü doğru şekilde yansıtamayacağını düşünüyorsanız, bu anlık görüntünün alınmasını önlemek için arama yapabilirsiniz .

Bunu söyledikten sonra, ekran görüntüsü hala alınmış gibi görünüyor ve bu nedenle bir hata raporu verdim. Ancak daha fazla test yapmalı ve bu ayarı kullanmanın yardımcı olup olmadığına bakmalısınız.

Bu bir kurumsal uygulama olsaydı , Yapılandırma Profili Başvurusu'nun Sınırlamalar Yükü bölümünde allowScreenShotbelirtilen uygun ayarı da incelemek isteyebilirsiniz .


İşte ihtiyacım olanı gerçekleştiren bir uygulama. UIImageViewGizli bilgileri gizlemek için kendinizinkini sunabilir veya bir temsilci protokolü modelini kullanabilirsiniz:

//  SecureDelegate.h

#import <Foundation/Foundation.h>

@protocol SecureDelegate <NSObject>

- (void)hide:(id)object;
- (void)show:(id)object;

@end

Daha sonra uygulama temsilcisine bunun için bir mülk verdim:

@property (weak, nonatomic) id<SecureDelegate> secureDelegate;

Görünüm denetleyicim bunu ayarlar:

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    delegate.secureDelegate = self;
}

Görünüm denetleyicisi açıkça bu protokolü uygular:

- (void)hide:(id)object
{
    self.passwordLabel.alpha = 0.0;
}

- (void)show:(id)object
{
    self.passwordLabel.alpha = 1.0;
}

Ve son olarak, uygulama temsilcim bu protokol ve özellikten yararlanır:

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

Not, applicationWillResignActivetavsiye edilen yerine kullanıyorum applicationDidEnterBackground, çünkü diğerlerinin de belirttiği gibi, uygulama çalışırken ana sayfa düğmesine iki kez dokunduğunuzda ikincisi çağrılmaz.

Temsilci protokol modeli yerine tüm bunları işlemek için bildirimleri kullanabilmeyi diliyorum, ancak sınırlı testimde bildirimler yeterince zamanında ele alınmıyor, ancak yukarıdaki model iyi çalışıyor.


6
Burada bahsedildiği gibi stackoverflow.com/questions/18937313/… davranışın simülatörde cihazdakiyle her zaman aynı olmadığını unutmayın!
Michael Forrest

5
Değeri ne ignoreSnapshotOnNextApplicationLauncholursa olsun, burada açıklandığı gibi durum geri yüklemesi sırasında çalıştırılmazsa yöntem göz ardı edilir .
Charles A.

3
Ekran görüntüsü applicationDidEnterBackground'a kadar alınmadığı için applicationWillResignActive'de yapmanız gerekmez. Ana sayfa düğmesine iki kez dokunduğunuzda, ekran görüntüsü alınmaz; gördüğünüz ekran canlı. Doğrulamak için ekranınıza bir animasyon ekleyin, örneğin arka plan renkleri döngüsü. Daha sonra başka bir uygulama seçerseniz, applicationDidEnterBackground gerçek ekran görüntüsü alınmadan önce çağrılır.
honus

3
BTW, bir Apple mühendisi bana belgelerin ignoreSnapshotOnNextApplicationLaunchyanlış olduğunu, hepimizin gözlemlediği gibi bir anlık görüntünün alındığını, ancak bir sonraki lansmanda kullanılmayacağını bildirdi.
Rob

2
ignoreSnapshotOnNextApplicationLaunch, göründüğü gibi görünüyor: uygulama başlatılırken bir ekran görüntüsünün görüntülenmesini engelleme . Çoklu görev kullanıcı arayüzü ekran görüntüsünü veya uygulamanız başlatılmak yerine devam ettirilip sürdürülmediğini etkilemez.
Glenn Maynard

32

Başvurum için üzerinde çalıştığım çözüm bu:

Tommy'nin dediği gibi: WillResignActive uygulamasını kullanabilirsiniz. Yaptığım şey, SplashImage'ımla bir UIImageView yapmak ve ana pencereme alt görünüm olarak eklemek oldu.

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

Bu yöntemi applicationDidEnterBackground yerine kullandım çünkü home düğmesine iki kez dokunursanız applicationDidEnterBackground tetiklenmeyecek ve applicationWillResignActive etkin olacaktır. İnsanların diğer durumlarda da tetiklenebileceğini söylediğini duydum, bu yüzden hala sorun yaratıp yaratmadığını görmek için etrafta test ediyorum, ancak şimdiye kadar hiçbiri yok! ;)

Görüntü görünümünü kaldırmak için:

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

Bu yardımcı olur umarım!

Not: Bunu hem simülatörde hem de gerçek bir cihazda test ettim: Simülatörde Gösterilmeyecek, ancak gerçek bir cihazda görünüyor!


2
Bir dezavantajı var: applicationWillResignActive, diğer durumların yanı sıra kullanıcı bildirim bölmesini aşağı çektiğinde çağrılır. Böylece, uygulama içeriğini görmeyi beklerken parmağınızı yukarıdan aşağıya kaydırır ve bu resmi görürsünüz.
Kirill Gamazkov

4
ApplicationWillResignActive'daki hassas bilgileri bulanıklaştırmak ve applicationDidEnterBackground'da imageView'i ayarlamak daha iyidir
Kirill Gamazkov

Bu işe yarıyor, ancak iOS7'ye dağıtıldığında, xCode6 ile oluşturulmuş bir döndürme hatası var: stackoverflow.com/questions/26147068/…
Alex Stone 14

ApplicationWillResignActive'da bahsettiğiniz kodu yazarsam, Uygulamamı ön plana geri getirdiğimde ne göreceğim? "Portrait (768x1024) .png" görüntüsünü mü yoksa gerçek ekranı mı göreceğim?
NSPratik

2
@Pratik: applicationDidBecomeActive yönteminde tekrar kaldırmadığınız sürece resmi göreceksiniz (yukarıya bakın).
Laura

14

Bu hızlı ve kolay yöntem, iOS7 veya sonraki uygulama değiştiricide uygulamanızın simgesinin üzerinde siyah bir anlık görüntü sağlar.

Öncelikle, uygulamanızın anahtar penceresini alın (genellikle uygulamada AppDelegate.m'de kurulur: didFinishLaunchingWithOptions) ve uygulamanız arka plana taşınmak üzereyken onu gizleyin:

- (void)applicationWillResignActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        self.window.hidden = YES;
    }
}

Ardından, uygulamanız tekrar etkin hale geldiğinde uygulamanızın anahtar penceresinin gizlemesini kaldırın:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        self.window.hidden = NO;
    }
}

Bu noktada, uygulama değiştiriciye göz atın ve uygulamanızın simgesinin üzerinde siyah bir anlık görüntü gördüğünüzü doğrulayın. Uygulamanızı arka plana taşıdıktan hemen sonra uygulama değiştiriciyi başlatırsanız, uygulamanızın anlık görüntüsünü (gizlemek istediğiniz!) Göreceğiniz yaklaşık 5 saniyelik bir gecikme olabileceğini fark ettim. tamamen siyah bir anlık görüntüye geçiş yapar. Gecikmenin ne olduğundan emin değilim; Herhangi birinin önerisi varsa, lütfen haber verin.

Anahtarlayıcıda siyah dışında bir renk istiyorsanız, istediğiniz herhangi bir arka plan rengine sahip bir alt görünüm ekleyerek bunun gibi bir şey yapabilirsiniz:

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

Ardından, uygulamanız tekrar etkin hale geldiğinde bu renk alt görünümünü kaldırın:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        UIView *colorView = [self.window viewWithTag:9999];
        [colorView removeFromSuperview];
    }
}

4

Aşağıdaki çözümü kullandım: uygulama terk edeceği zaman appWindow anlık görüntüsünü Görünüm olarak alıyorum ve ona bulanıklık ekliyorum. Sonra bu görünümü uygulama penceresine ekliyorum

bu nasıl yapılır:

  1. appDelegate uygulamasında uygulamadan hemen önce satır ekleyin:

    static const int kNVSBlurViewTag = 198490;//or wherever number you like
    
  2. bu yöntemleri ekleyin:

    - (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;
        }
    
  3. appDelegate uygulamanızı aşağıdaki gibi yapın:

    - (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 active state; here you can undo many of the changes made on entering the background.
        //...
        //your code
        //...
    
        [self nvs_unblurPresentedView];
    }
    

Swift ve Objective C'de Örnek projeler oluşturdum . Her iki proje de aşağıdaki eylemleri gerçekleştirir:

-application: didResignActive - anlık görüntü oluşturulur, bulanıklaştırılır ve uygulama penceresine eklenir

-application: willBecomeActive bulanıklık görünümü pencereden kaldırılıyor.

Nasıl kullanılır:

Objecitve C

  1. Ekle AppDelegate+NVSBlurAppScreenprojenize dosyaları .h ve .m

  2. -applicationWillResignActive: yönteminize aşağıdaki satırı ekleyin:

    [self nvs_blurPresentedView];
    
  3. -applicationDidEnterBackground: yönteminize aşağıdaki satırı ekleyin:

    [self nvs_unblurPresentedView];
    

Swift

  1. AppDelegateExtention.swift dosyasını projenize ekleyin

  2. uygulamanızdaWillResignActive işlevinde aşağıdaki satırı ekleyin:

    blurPresentedView()
    
  3. applicationDidBecomeActive işlevinize aşağıdaki satırı ekleyin:

    unblurPresentedView()
    

2

Sadece kullanırsanız [self.window addSubview:imageView];içinde applicationWillResignActiveişlev Bu imageview UIAlertView, UIActionSheet veya MFMailComposeViewController karşılamayacaktır ...

En iyi çözüm

- (void)applicationWillResignActive:(UIApplication *)application
{
    UIWindow *mainWindow = [[[UIApplication sharedApplication] windows] lastObject];
    [mainWindow addSubview:imageView];
}

Bir web görünümünde tam ekran modunda oynatılan bir videonuz varsa çok iyi bir çözüm!
Tommie

Mükemmel!. Çoklu görev değiştiriciye girmeden önce açık bir tuş takımımız olsa bile çalışır! Teşekkürler
Prabhu.Somasundaram

0

Bu çözüm çok güvenilmez olsa da, kendi çözümümü bir "cevap" olarak sunmak. Bazen ekran görüntüsü olarak siyah bir ekran, bazen XIB ve bazen de uygulamanın kendisinden bir ekran görüntüsü alıyorum. Cihaza bağlı olarak ve / veya bunu simülatörde çalıştırırsam.

Bu çözüm için herhangi bir kod sağlayamayacağımı lütfen unutmayın, çünkü orada çok sayıda uygulamaya özgü ayrıntı var. Ancak bu, çözümümün temel özünü açıklamalıdır.

AppDelegate.m'de applicationWillResignActive altında iOS7 çalıştırıp çalıştırmadığımızı kontrol ediyorum, eğer yaparsak ortada uygulama logosu ile boş olan yeni bir görünüm yüklerim. ApplicationDidBecomeActive olarak adlandırıldıktan sonra eski görünümlerimi yeniden başlatırım, bu sıfırlanacaktır - ancak bu, geliştirmekte olduğum uygulama türü için çalışır.


1
Kamera uygulamasının ne yaptığını görürseniz - arka plana geçerken görüntüyü bulanık bir hale dönüştürür (geçişi simgeye
küçülürken görebilirsiniz

@Petesh Evet, bu güzel bir uygulama, ama soru bunu nasıl yaptıkları. Özel bir API'den korkuyorum.
Rob

@Tommie "Cihaza bağlı olarak ve / veya bunu simülatörde çalıştırırsam" diyorsunuz. Benim için, cihaz üzerinde çalışıyor gibi görünüyor (kapsamlı testler yapmadım ama simülatörde değil). Cihazda çalışmadığını mı anlıyorsunuz?
Rob

0

Çoklu görevi başlatmak ve varsayılan ana sayfa düğmesine çift tıklamayı ve çoklu görev penceresini başlatmayı devre dışı bırakmak için ana düğmeye çift tıklamayı yapılandırmak için etkinleştiriciyi kullanabilirsiniz. Bu yöntem, ekran görüntülerini uygulamanın varsayılan görüntüsüne değiştirmek için kullanılabilir. Bu, varsayılan şifre koruma özelliğine sahip uygulamalar için geçerlidir.


-2

Xamarin.iOS

Https://stackoverflow.com/a/20040270/7561 adresinden uyarlanmıştır

Sadece bir renk göstermek yerine başlatma ekranımı göstermek istedim.

 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();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.