Ich schreibe eine App und muss die Ansicht ändern, wenn der Benutzer die App ansieht, während er telefoniert.
Ich habe die folgende Methode implementiert:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
Es wird jedoch nicht aufgerufen, wenn die App wieder in den Vordergrund zurückkehrt.
Ich weiß, dass ich Folgendes implementieren kann:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
aber ich will das nicht tun. Ich würde viel lieber alle meine Layoutinformationen in die viewWillAppear: -Methode einfügen und diese alle möglichen Szenarien behandeln lassen.
Ich habe sogar versucht, viewWillAppear: von applicationWillEnterForeground: aufzurufen, aber ich kann anscheinend nicht genau bestimmen, welcher der aktuelle Ansichts-Controller zu diesem Zeitpunkt ist.
Kennt jemand den richtigen Weg, um damit umzugehen? Ich bin sicher, ich vermisse eine offensichtliche Lösung.
quelle
applicationWillEnterForeground:
um festzustellen, wann Ihre Anwendung wieder in den aktiven Status eingetreten ist.isMemberOfClass
oder verwendenisKindOfClass
, je nach Ihren Bedürfnissen.Antworten:
Die Methode
viewWillAppear
sollte im Kontext dessen verwendet werden, was in Ihrer eigenen Anwendung vor sich geht, und nicht im Kontext Ihrer Anwendung, die in den Vordergrund gestellt wird, wenn Sie von einer anderen App zurück zu ihr wechseln.Mit anderen Worten, wenn jemand eine andere Anwendung ansieht oder einen Anruf entgegennimmt, wechselt er zurück zu Ihrer App, die zuvor im Hintergrund war. Ihr UIViewController, der bereits sichtbar war, als Sie Ihre App verlassen haben, ist sozusagen "egal". Was es betrifft, ist es nie verschwunden und immer noch sichtbar - und so
viewWillAppear
nicht genannt.Ich empfehle, sich nicht
viewWillAppear
selbst anzurufen - es hat eine bestimmte Bedeutung, die Sie nicht untergraben sollten! Ein Refactoring, das Sie durchführen können, um den gleichen Effekt zu erzielen, könnte wie folgt aussehen:Dann lösen Sie auch
doMyLayoutStuff
aus der entsprechenden Benachrichtigung aus:Es gibt übrigens keinen sofort einsatzbereiten Weg, um festzustellen, welcher der 'aktuelle' UIViewController ist. Sie können jedoch Wege finden, um dies zu umgehen, z. B. gibt es delegierte Methoden von UINavigationController, um herauszufinden, wann ein UIViewController darin präsentiert wird. Sie können so etwas verwenden, um den neuesten UIViewController zu verfolgen, der vorgestellt wurde.
Aktualisieren
Wenn Sie Benutzeroberflächen mit den entsprechenden Masken für die automatische Größenänderung für die verschiedenen Bits auslegen, müssen Sie sich manchmal nicht einmal mit dem manuellen Layout Ihrer Benutzeroberfläche befassen - es wird nur ...
quelle
self.navigationController.topViewController
effektiv zur Verfügung stelle , oder zumindest den oben auf dem Stapel, der der wäre Aktueller, wenn dieser Code auf den Haupt-Thread in einem Ansichts-Controller ausgelöst wird. (Könnte falsch sein, habe nicht viel damit gespielt, scheint aber zu funktionieren.)appDelegate.rootViewController
wird auch funktionieren, aber es könnte ein zurückgebenUINavigationController
, und dann brauchen Sie,.topViewController
wie @MatthewFrederick sagt.Schnell
Kurze Antwort
Verwenden Sie
NotificationCenter
lieber einen Beobachter alsviewWillAppear
.Lange Antwort
Verwenden Sie einen
NotificationCenter
Beobachter anstelle von, um herauszufinden, wann eine App aus dem Hintergrund zurückkommtviewWillAppear
. Hier ist ein Beispielprojekt, das zeigt, welche Ereignisse wann auftreten. (Dies ist eine Anpassung dieser Objective-C-Antwort .)Beim ersten Start der App lautet die Ausgabereihenfolge:
Nachdem Sie die Home-Taste gedrückt und die App wieder in den Vordergrund gebracht haben, lautet die Ausgabereihenfolge:
Also , wenn Sie wurden ursprünglich versucht , zu verwenden ,
viewWillAppear
dannUIApplication.willEnterForegroundNotification
ist wahrscheinlich das, was Sie wollen.Hinweis
Ab iOS 9 müssen Sie den Beobachter nicht mehr entfernen. In der Dokumentation heißt es:
quelle
Verwenden Sie das Notification Center in der
viewDidLoad:
Methode Ihres ViewControllers, um eine Methode aufzurufen und von dort aus das zu tun, was Sie in IhrerviewWillAppear:
Methode tun sollten .viewWillAppear:
Direkt anrufen ist keine gute Option.quelle
dealloc
dann methodisch zu entfernen .viewWillAppear:animated:
Eine meiner Meinung nach verwirrendste Methode in den iOS-SDKs wird in einer solchen Situation, dh beim Wechseln von Anwendungen, niemals aufgerufen. Diese Methode wird nur gemäß der Beziehung zwischen der Ansicht des Ansichtscontrollers und dem Fenster der Anwendung aufgerufen , dh die Nachricht wird nur dann an einen Ansichtscontroller gesendet, wenn ihre Ansicht im Fenster der Anwendung und nicht auf dem Bildschirm angezeigt wird.Wenn Ihre Anwendung in den Hintergrund tritt, sind die obersten Ansichten des Anwendungsfensters für den Benutzer offensichtlich nicht mehr sichtbar. In der Perspektive Ihres Anwendungsfensters sind sie jedoch immer noch die obersten Ansichten und daher nicht aus dem Fenster verschwunden. Diese Ansichten verschwanden vielmehr, weil das Anwendungsfenster verschwand. Sie sind nicht verschwunden, weil sie vom Fenster verschwunden sind .
Wenn der Benutzer zu Ihrer Anwendung zurückkehrt, werden sie offensichtlich auf dem Bildschirm angezeigt, da das Fenster erneut angezeigt wird. Aber aus der Sicht des Fensters sind sie überhaupt nicht verschwunden. Daher erhalten die View Controller die
viewWillAppear:animated
Nachricht nie .quelle
Swift 4.2 / 5
quelle
Ich versuche nur, es so einfach wie möglich zu machen, siehe Code unten:
quelle