web-dev-qa-db-fra.com

Afficher une vue ou un écran de démarrage avant applicationDidEnterBackground (pour éviter la capture d'écran de la vue active)

J'ai des informations confidentielles dans mon application, je voudrais donc les masquer avec un écran de démarrage lorsque l'application est sur le point d'être déplacée en arrière-plan.

Je lance l'application sur iOS6 et plus encore.

J'ai essayé d'afficher la vue dans applicationWillResignActive mais le problème est qu'il affiche l'écran de démarrage même lorsque l'utilisateur glisse le panneau de configuration par exemple. Je souhaite qu'il s'affiche uniquement lorsque l'application est déplacée en arrière-plan.

J'ai essayé d'afficher mon splashScreen dans applicationDidEnterBackground mais il faut la capture d'écran avant donc les informations sont affichées à la restauration pendant l'animation.

Voici l'esprit de ce que je veux:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [_window addSubview:__splashController.view];
}
33
AncAinu

Je pense que le problème est que vous testez dans le simulateur . Sur l'appareil, cela devrait fonctionner correctement.

J'ai testé cela et cela a fonctionné. Ajoutez une vue d'image avec votre image de démarrage lorsque l'application entre en arrière-plan -

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

Et lorsque l'application revient au premier plan -

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    UIImageView *imageView = (UIImageView *)[UIApplication.sharedApplication.keyWindow.subviews.lastObject viewWithTag:101];   // search by the same tag value
    [imageView removeFromSuperview];

}

REMARQUE - Sur le simulateur (iOS 7.0), la sous-vue ajoutée ne s'affiche pas lorsque vous vérifiez en appuyant deux fois sur le bouton d'accueil (Cmd + H), mais sur l'appareil, cela fonctionne comme prévu (comme Paypal, BofA applications)

MODIFIER: (Informations supplémentaires)

En plus de masquer/remplacer les informations sensibles en ajoutant une sous-vue/flou comme expliqué ci-dessus, iOS 7 vous offre la possibilité d'ignorer la capture d'écran via ignoreSnapshotOnNextApplicationLaunch de UIApplication à l'intérieur de applicationWillResignActive ou 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);

De plus, l'indicateur allowScreenShot peut être exploré dans Restrictions Payload .

39
Ashok

Réponse Swift 3. pour ceux qui sont trop paresseux pour traduire.

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()
    }

}
8
SteffenK

J'ai eu le même problème, j'utilisais essentiellement applicationDidEnterBackground pour afficher une fenêtre d'interface utilisateur au-dessus du contenu, mais dans iOS8, cela ne fonctionnait pas comme dans iOS7.

La solution que j'ai trouvée a été de créer l'UIWindow dans applicationWillResignActive mais de le masquer securityWindow.hidden = YES; puis dans applicationDidEnterBackground tout ce que je ferais serait de changer securityWindow.hidden = NO.

Cela semble fonctionner exactement comme iOS7 masquant le contenu lors de tâches multiples sans affecter la vue lors de l'utilisation de NotificationCenter ou ControlPanel.

4
SharkBait

Je ne sais pas pourquoi, mais aucune des méthodes décrites ici n'a fonctionné pour moi. J'essayais simplement de couvrir l'écran pour des raisons de sécurité. Donc, ce qui a aidé était un Q&A technique d'Apple: https://developer.Apple.com/library/ios/qa/qa1838/_index.html

Je suppose que la principale différence est d'utiliser un UIViewController? Quoi qu'il en soit, le code suivant fonctionne parfaitement pour moi sur 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];
}
2
Ertan D.

Besoin d'écrire le code comme suit:

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

Ici pour supprimer l'imageview:

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

Il fonctionne et est correctement testé.

2
Deepak Kumar
@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
0
neoneye

Cela m'a corrigé, désolé, c'est pour Xamarin.Forms mais vous devriez avoir l'idée. Vous devez appeler UIView.SnapshotView (true) dans xamarin ou UIView snapshotViewAfterScreenUpdates sur iOS. Fonctionne dans DidEnterBackground sur iOS7 et iOS8:

public override void DidEnterBackground(UIApplication uiApplication)
{
    App.Current.MainPage = new DefaultPage();
    **UIApplication.SharedApplication.KeyWindow.SnapshotView(true);**
    base.DidEnterBackground(uiApplication);
}
0
shane

Je pense que cela aidera Swift 3.

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()
        }
    }
0
Blahji