J'ai un contrôleur de vue dans lequel ma valeur est 0 (étiquette) et lorsque j'ouvre ce contrôleur de vue à partir d'un autre, ViewController
j'ai viewDidAppear
défini la valeur 20 sur l'étiquette. Il fonctionne très bien , mais quand je ferme mon application et que de nouveau j'ouvrir mon application , mais la valeur ne change pas parce que viewDidLoad
, viewDidAppear
et viewWillAppear
rien ne s'appelle. Comment puis-je appeler lorsque j'ouvre mon application. Dois-je faire quelque chose à partir de applicationDidBecomeActive
?
176
Réponses:
Curieux de connaître la séquence exacte des événements, j'ai instrumenté une application comme suit: (@Zohaib, vous pouvez utiliser le code NSNotificationCenter ci-dessous pour répondre à votre question).
// AppDelegate.m - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"app will enter foreground"); } - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"app did become active"); } // ViewController.m - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"view did load"); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; } - (void)appDidBecomeActive:(NSNotification *)notification { NSLog(@"did become active notification"); } - (void)appWillEnterForeground:(NSNotification *)notification { NSLog(@"will enter foreground notification"); } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSLog(@"view will appear"); } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSLog(@"view did appear"); }
Au lancement, la sortie ressemble à ceci:
2013-04-07 09:31:06.505 myapp[15459:11303] view did load 2013-04-07 09:31:06.507 myapp[15459:11303] view will appear 2013-04-07 09:31:06.511 myapp[15459:11303] app did become active 2013-04-07 09:31:06.512 myapp[15459:11303] did become active notification 2013-04-07 09:31:06.517 myapp[15459:11303] view did appear
Entrez l'arrière-plan puis entrez à nouveau au premier plan:
2013-04-07 09:32:05.923 myapp[15459:11303] app will enter foreground 2013-04-07 09:32:05.924 myapp[15459:11303] will enter foreground notification 2013-04-07 09:32:05.925 myapp[15459:11303] app did become active 2013-04-07 09:32:05.926 myapp[15459:11303] did become active notification
la source
Utilisation d'Objective-C
Vous devez vous inscrire un
UIApplicationWillEnterForegroundNotification
dans votreViewController
deviewDidLoad
méthode et chaque fois que l' application revient de fond que vous pouvez faire ce que vous voulez faire dans la méthode enregistrées pour la notification.ViewController
« s viewWillAppear ou viewDidAppear ne seront pas appelées lorsque l' application revient de fond au premier plan.-(void)viewDidLoad{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doYourStuff) name:UIApplicationWillEnterForegroundNotification object:nil]; } -(void)doYourStuff{ // do whatever you want to do when app comes back from background. }
N'oubliez pas de désenregistrer la notification pour laquelle vous êtes inscrit.
-(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
Notez que si vous enregistrez votre
viewController
pour,UIApplicationDidBecomeActiveNotification
votre méthode sera appelée chaque fois que votre application devient active, il n'est pas recommandé de vous inscrireviewController
à cette notification.Utilisation de Swift
Pour ajouter un observateur, vous pouvez utiliser le code suivant
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: "doYourStuff", name: UIApplication.willEnterForegroundNotification, object: nil) } func doYourStuff(){ // your code }
Pour supprimer l'observateur, vous pouvez utiliser la fonction deinit de swift.
deinit { NotificationCenter.default.removeObserver(self) }
la source
Version Swift 3.0 ++
Dans votre
viewDidLoad
, inscrivez-vous au centre de notification pour écouter cette action ouverte en arrière-planNotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
Ajoutez ensuite cette fonction et effectuez l'action nécessaire
func doSomething(){ //... }
Enfin, ajoutez cette fonction pour nettoyer l'observateur de notification lorsque votre contrôleur de vue est détruit.
deinit { NotificationCenter.default.removeObserver(self) }
la source
Swift 4.2. version
Inscrivez-vous au NotificationCenter
viewDidLoad
pour être averti lorsque l'application revient de l'arrière-planNotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)
Implémentez la méthode qui doit être appelée.
@objc private func doSomething() { // Do whatever you want, for example update your view. }
Vous pouvez supprimer l'observateur une fois le
ViewController
fichier détruit. Ceci n'est requis que sous iOS9 et macOS 10.11deinit { NotificationCenter.default.removeObserver(self) }
la source
Demandez simplement à votre contrôleur de vue de s'inscrire à la
UIApplicationWillEnterForegroundNotification
notification et de réagir en conséquence.la source
viewDidLoad
comme @nsgulliver suggéré. VousviewDidAppear
appellerez égalementdoYourStuff
pour définir votre étiquette avec la valeur souhaitée.Je pense que l'inscription à UIApplicationWillEnterForegroundNotification est risquée car vous pouvez vous retrouver avec plus d'un contrôleur réagissant à cette notification. Rien ne garantit que ces contrôleurs sont toujours visibles lorsque la notification est reçue.
Voici ce que je fais: Je force l'appel viewDidAppear sur le contrôleur actif directement à partir de la méthode didBecomeActive du délégué de l'application:
Ajoutez le code ci-dessous à
- (void)applicationDidBecomeActive:(UIApplication *)application
UIViewController *activeController = window.rootViewController; if ([activeController isKindOfClass:[UINavigationController class]]) { activeController = [(UINavigationController*)window.rootViewController topViewController]; } [activeController viewDidAppear:NO];
la source
essayez d'ajouter cela dans AppDelegate applicationWillEnterForeground.
func applicationWillEnterForeground(_ application: UIApplication) { // makes viewWillAppear run self.window?.rootViewController?.beginAppearanceTransition(true, animated: false) self.window?.rootViewController?.endAppearanceTransition() }
la source
Selon la documentation d'Apple:
(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;
Description:
indique à un contrôleur enfant que son apparence est sur le point de changer. Si vous implémentez un contrôleur de conteneur personnalisé, utilisez cette méthode pour indiquer à l'enfant que ses vues sont sur le point d' apparaître ou de disparaître . Ne pas invoquer
viewWillAppear:
,viewWillDisappear:
,viewDidAppear:
ouviewDidDisappear:
directement .(void)endAppearanceTransition;
La description:
Indique à un contrôleur enfant que son apparence a changé. Si vous implémentez un contrôleur de conteneur personnalisé, utilisez cette méthode pour indiquer à l'enfant que la transition de vue est terminée.
Exemple de code:
(void)applicationDidEnterBackground:(UIApplication *)application { [self.window.rootViewController beginAppearanceTransition: NO animated: NO]; // I commented this line [self.window.rootViewController endAppearanceTransition]; // I commented this line }
Question: Comment j'ai réparé?
Ans : J'ai trouvé ce morceau de lignes en application. Ces lignes ont fait que mon application ne recevait aucune notification ViewWillAppear. Quand j'ai commenté ces lignes, cela fonctionne très bien .
la source