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 réglé viewDidAppear
sur la valeur 20 de l'étiquette. Cela fonctionne bien, mais lorsque je ferme mon application et que je l'ouvre à nouveau, mais la valeur ne change pas, car viewDidLoad
, viewDidAppear
et viewWillAppear
rien n'est appelé. Comment puis-je appeler lorsque j'ouvre mon application? Dois-je faire quelque chose de applicationDidBecomeActive
?
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 ré-entrez 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
en utilisant Objective-C
Vous devez enregistrer un UIApplicationWillEnterForegroundNotification
dans votre méthode ViewController
's viewDidLoad
et chaque fois que l'application revient de l'arrière-plan, vous pouvez faire ce que vous voulez dans la méthode enregistrée pour la notification. ViewController
'viewWillAppear ou viewDidAppear ne sera pas appelé lorsque l'application reviendra de l'arrière-plan à l'avant-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 enregistré.
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Note Si vous enregistrez votre viewController
pour UIApplicationDidBecomeActiveNotification
, votre méthode sera appelée à chaque fois que votre application devient active. Il est déconseillé d'enregistrer viewController
pour cette notification. .
en utilisant Swift
Pour ajouter observateur, vous pouvez utiliser le code suivant
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"doYourStuff", name:
UIApplicationWillEnterForegroundNotification, object: nil)
}
func doYourStuff(){
// your code
}
Pour supprimer l'observateur, vous pouvez utiliser la fonction deinit de Swift.
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Dans votre viewDidLoad
, enregistrez-vous dans le centre de notification pour écouter cette action ouverte à partir de l'arrière-plan.
NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
Ajoutez ensuite cette fonction et effectuez l'action requise.
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)
}
Inscrivez-vous auprès de NotificationCenter dans viewDidLoad
pour être averti lorsque l'application revient de l'arrière-plan
NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)
Implémentez la méthode à appeler.
@objc private func doSomething() {
// Do whatever you want, for example update your view.
}
Vous pouvez supprimer l'observateur une fois que la ViewController
est détruite. Ceci n'est requis que sous iOS9 et macOS 10.11
deinit {
NotificationCenter.default.removeObserver(self)
}
Je pense que s’inscrire à la notification UIApplicationWillEnterForegroundNotification est risqué car il est possible que plusieurs contrôleurs réagissent à cette notification. Rien ne garantit que ces contrôleurs sont toujours visibles lors de la réception de la notification.
Voici ce que je fais: Je force l'appel de viewDidAppear sur le contrôleur actif directement depuis 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];
Demandez à votre contrôleur de vue de s’enregistrer pour la notification UIApplicationWillEnterForegroundNotification
et réagissez en conséquence.
essayez d'ajouter ceci dans AppDelegate applicationWillEnterForeground.
func applicationWillEnterForeground(_ application: UIApplication) {
// makes viewWillAppear run
self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
self.window?.rootViewController?.endAppearanceTransition()
}
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 de apparaître ou disparaître. Ne pas invoquer viewWillAppear:
, viewWillDisappear:
, viewDidAppear:
ou viewDidDisappear:
directement).
(void)endAppearanceTransition;
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 corrigé?
Ans: J'ai trouvé ce morceau de lignes en application. Cela a rendu mon application ne recevant aucune notification ViewWillAppear. Quand j'ai commenté ces lignes ça marche très bien.