Ich habe einen View Controller, in dem mein Wert 0 (label) ist, und wenn ich diesen View Controller von einem anderen ViewController
aus öffne, habe ich viewDidAppear
so eingestellt, dass auf label der Wert 20 eingestellt ist. Es funktioniert einwandfrei, aber wenn ich meine App schließe und dann wieder öffne, ändert sich der Wert nicht, da viewDidLoad
, viewDidAppear
und viewWillAppear
nichts aufgerufen werden. Wie kann ich anrufen, wenn ich meine App öffne? Muss ich irgendetwas von applicationDidBecomeActive
tun?
Neugierig auf die genaue Abfolge der Ereignisse, habe ich eine App wie folgt instrumentiert: (@Zohaib, Sie können den folgenden NSNotificationCenter-Code verwenden, um Ihre Frage zu beantworten).
// 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");
}
Beim Start sieht die Ausgabe folgendermaßen aus:
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
Geben Sie den Hintergrund ein und geben Sie den Vordergrund erneut ein:
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
nter Verwendung von Objective-C
Sie sollten ein UIApplicationWillEnterForegroundNotification
in der ViewController
-Methode Ihrer viewDidLoad
registrieren. Wenn die App aus dem Hintergrund zurückkehrt, können Sie mit der für die Benachrichtigung registrierten Methode alle gewünschten Aktionen ausführen. ViewController
s viewWillAppear oder viewDidAppear werden nicht aufgerufen, wenn die App vom Hintergrund in den Vordergrund zurückkehrt.
-(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.
}
Vergessen Sie nicht, die Registrierung der Benachrichtigung, für die Sie registriert sind, aufzuheben.
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Hinweis Wenn Sie viewController
für UIApplicationDidBecomeActiveNotification
registrieren, wird Ihre Methode jedes Mal aufgerufen, wenn Ihre App aktiv wird. Es wird nicht empfohlen, viewController
zu registrieren. für diese Benachrichtigung.
Mit Swift
Zum Hinzufügen eines Beobachters können Sie den folgenden Code verwenden
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"doYourStuff", name:
UIApplicationWillEnterForegroundNotification, object: nil)
}
func doYourStuff(){
// your code
}
Zum Entfernen des Beobachters können Sie die Deinit-Funktion von Swift verwenden.
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Registrieren Sie sich in Ihrem viewDidLoad
im Benachrichtigungscenter, um die im Hintergrund geöffnete Aktion anzuhören
NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
Fügen Sie dann diese Funktion hinzu und führen Sie die erforderlichen Aktionen aus
func doSomething(){
//...
}
Fügen Sie diese Funktion schließlich hinzu, um den Benachrichtigungsbeobachter zu bereinigen, wenn Ihr Ansichtscontroller zerstört wird.
deinit {
NotificationCenter.default.removeObserver(self)
}
Registrieren Sie sich im NotificationCenter in viewDidLoad
, um benachrichtigt zu werden, wenn die App aus dem Hintergrund zurückkehrt
NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)
Implementieren Sie die aufzurufende Methode.
@objc private func doSomething() {
// Do whatever you want, for example update your view.
}
Sie können den Beobachter entfernen, sobald das ViewController
zerstört ist. Dies ist nur unter iOS9 und macOS 10.11 erforderlich
deinit {
NotificationCenter.default.removeObserver(self)
}
Ich denke, die Registrierung für die UIApplicationWillEnterForegroundNotification ist riskant, da möglicherweise mehr als ein Controller auf diese Benachrichtigung reagiert. Nichts garantiert, dass diese Controller zum Zeitpunkt des Eingangs der Benachrichtigung noch sichtbar sind.
Ich erzwinge den Aufruf von viewDidAppear auf dem aktiven Controller direkt von der didBecomeActive-Methode des App-Delegaten:
Fügen Sie den folgenden Code zu - (void)applicationDidBecomeActive:(UIApplication *)application
hinzu
UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];
Lassen Sie einfach Ihren View Controller für die Benachrichtigung UIApplicationWillEnterForegroundNotification
registrieren und reagieren Sie entsprechend.
fügen Sie dies in AppDelegate applicationWillEnterForeground hinzu.
func applicationWillEnterForeground(_ application: UIApplication) {
// makes viewWillAppear run
self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
self.window?.rootViewController?.endAppearanceTransition()
}
Gemäß der Dokumentation von Apple:
(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;
Beschreibung:
Sagt einem untergeordneten Controller, dass sich sein Erscheinungsbild bald ändern wird. Wenn Sie einen benutzerdefinierten Container-Controller implementieren, teilen Sie dem untergeordneten Element mit, dass seine Ansichten im Begriff sind angezeigt oder ausgeblendet. Rufen Sie viewWillAppear:
, viewWillDisappear:
, viewDidAppear:
Oder viewDidDisappear:
Nicht direkt auf..
(void)endAppearanceTransition;
Beschreibung:
Sagt einem untergeordneten Controller, dass sich sein Erscheinungsbild geändert hat. Wenn Sie einen benutzerdefinierten Container-Controller implementieren, teilen Sie dem untergeordneten Element mit, dass der Ansichtsübergang abgeschlossen ist.
Beispielcode:
(void)applicationDidEnterBackground:(UIApplication *)application
{
[self.window.rootViewController beginAppearanceTransition: NO animated: NO]; // I commented this line
[self.window.rootViewController endAppearanceTransition]; // I commented this line
}
Frage: Wie habe ich behoben?
Ans: Ich habe diese Zeilen in der Anwendung gefunden. Aufgrund dieser Zeilen erhielt meine App keine ViewWillAppear-Benachrichtigungen. Wenn ich diese Zeilen kommentiert habe, funktioniert es gut.