it-swarm.com.de

ViewDidAppear wird beim Öffnen der App im Hintergrund nicht aufgerufen

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?

164
Zohaib

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
303
lara

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. ViewControllers 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)
}
130
nsgulliver

Swift 3.0 ++ Version

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)
}
42
Fangming

Swift 4.2. Ausführung

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)
}
6
gebirgsbärbel

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];
3
Erwan

Lassen Sie einfach Ihren View Controller für die Benachrichtigung UIApplicationWillEnterForegroundNotification registrieren und reagieren Sie entsprechend.

3
andreagiavatto

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

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.

2
Lakshmi