Ich muss einige Aktionen ausführen, wenn die Schaltfläche Zurück (Zurück zum vorherigen Bildschirm, Zurück zur übergeordneten Ansicht) auf einer Navigationsleiste gedrückt wird.
Gibt es eine Methode, die ich implementieren kann, um das Ereignis abzufangen und einige Aktionen auszulösen, um Daten anzuhalten und zu speichern, bevor der Bildschirm verschwindet?
iphone
objective-c
ios
xcode
ewok
quelle
quelle
Antworten:
UPDATE: Laut einigen Kommentaren scheint die Lösung in der ursprünglichen Antwort unter bestimmten Szenarien in iOS 8+ nicht zu funktionieren. Ich kann ohne weitere Details nicht überprüfen, ob dies tatsächlich der Fall ist.
Für diejenigen von Ihnen gibt es jedoch in dieser Situation eine Alternative. Durch Überschreiben kann festgestellt werden, wann ein Ansichts-Controller geöffnet wird
willMove(toParentViewController:)
. Die Grundidee ist, dass ein Ansichts-Controller angezeigt wird, wenn er angezeigtparent
wirdnil
.Weitere Informationen finden Sie unter "Implementieren eines Container View Controllers" .
Seit iOS 5 habe ich festgestellt, dass der einfachste Weg, mit dieser Situation umzugehen, die neue Methode ist
- (BOOL)isMovingFromParentViewController
:- (BOOL)isMovingFromParentViewController
Dies ist sinnvoll, wenn Sie Controller in einem Navigationsstapel verschieben und platzieren.Wenn Sie jedoch modale Ansichtssteuerungen präsentieren, sollten Sie
- (BOOL)isBeingDismissed
stattdessen Folgendes verwenden :Wie in dieser Frage erwähnt , können Sie beide Eigenschaften kombinieren:
Andere Lösungen beruhen auf der Existenz von a
UINavigationBar
. Stattdessen mag ich meinen Ansatz eher, weil er die erforderlichen Aufgaben von der Aktion, die das Ereignis ausgelöst hat, entkoppelt, dh eine Zurück-Taste drückt.quelle
self.isMovingFromParentViewController
hat den Wert TRUE, wenn ich den Navigationsstapel programmgesteuert mit öffnepopToRootViewControllerAnimated
- ohne die Zurück-Taste zu berühren. Sollte ich Ihre Antwort ablehnen? (Das Thema sagt "'Zurück' Taste ist auf einer Navigationsleiste gedrückt")override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) if isMovingFromParentViewController(){ println("back button pressed") } }
-viewDidDisappear:
da es möglich ist, dass Sie ein-viewWillDisappear:
ohne ein erhalten-viewDidDisappear:
(wie wenn Sie mit dem Wischen beginnen, um ein Navigationscontroller-Element zu schließen und dieses Wischen dann abzubrechen.Während
viewWillAppear()
undviewDidDisappear()
werden aufgerufen , wenn die Zurück - Taste abgegriffen wird, werden sie auch zu anderen Zeiten genannt. Weitere Informationen hierzu finden Sie am Ende der Antwort.Verwenden von UIViewController.parent
Das Erkennen der Zurück-Schaltfläche ist besser, wenn der VC mithilfe von
willMoveToParentViewController(_:)
OR von seinem übergeordneten Element (dem NavigationController) entfernt wirddidMoveToParentViewController()
Wenn übergeordnetes Element Null ist, wird der Ansichts-Controller vom Navigationsstapel entfernt und geschlossen. Wenn übergeordnetes Element nicht Null ist, wird es dem Stapel hinzugefügt und angezeigt.
Swap - out
willMove
fürdidMove
und Check self.parent zu tun Arbeit nach der View - Controller des Feldes verwiesen.Die Entlassung stoppen
Beachten Sie, dass Sie beim Überprüfen des übergeordneten Elements den Übergang nicht "anhalten" können, wenn Sie eine Art asynchrones Speichern durchführen müssen. Dazu können Sie Folgendes implementieren. Der einzige Nachteil hierbei ist, dass Sie den ausgefallenen iOS-gestalteten / animierten Zurück-Button verlieren. Seien Sie auch hier vorsichtig mit der interaktiven Wischgeste. Verwenden Sie Folgendes, um diesen Fall zu behandeln.
Weitere Informationen werden / wurden angezeigt
Wenn Sie das
viewWillAppear
viewDidDisappear
Problem nicht erhalten haben , lassen Sie uns ein Beispiel durchgehen. Angenommen, Sie haben drei Ansichts-Controller:Lets folgen auf die die Anrufe ,
detailVC
wie Sie von unterwegslistVC
aufsettingsVC
und zurück zulistVC
Liste> Detail (Push DetailVC)
Detail.viewDidAppear
<-Detail anzeigen > Einstellungen (Push SettingsVC)
Detail.viewDidDisappear
<- verschwindenUnd wenn wir zurückgehen ...
Einstellungen> Detail (Pop-EinstellungenVC)
Detail.viewDidAppear
<-Detail anzeigen > Liste (Pop-DetailVC)
Detail.viewDidDisappear
<- verschwindenBeachten Sie, dass dies
viewDidDisappear
mehrmals aufgerufen wird, nicht nur beim Zurückgehen, sondern auch beim Vorwärtsgehen. Für einen schnellen Vorgang, der möglicherweise erwünscht ist, für einen komplexeren Vorgang wie das Speichern eines Netzwerkaufrufs jedoch möglicherweise nicht.quelle
didMoveToParantViewController:
muss arbeiten, wenn die Ansicht nicht mehr sichtbar ist. Hilfreich für iOS7 mit dem interaktivenGesutre_ = self.navigationController?.popViewController(animated: true)
, sodass es nicht nur beim Drücken der Zurück-Taste aufgerufen wird. Ich suche einen Anruf, der nur funktioniert , wenn Zurück gedrückt wird.Erste Methode
Zweite Methode
quelle
Diejenigen, die behaupten, dass dies nicht funktioniert, irren sich:
Das funktioniert gut. Was verursacht also den weit verbreiteten Mythos, dass dies nicht der Fall ist?
Das Problem scheint auf eine fehlerhafte Implementierung einer anderen Methode zurückzuführen zu sein, nämlich auf die Implementierung eines
willMove(toParent:)
vergessenen Aufrufssuper
.Wenn Sie
willMove(toParent:)
ohne Aufruf implementierensuper
,self.isMovingFromParent
wird dies seinfalse
und die Verwendung vonviewWillDisappear
scheint fehlzuschlagen. Es ist nicht gescheitert; du hast es kaputt gemacht.HINWEIS: Das eigentliche Problem besteht normalerweise darin, dass der zweite Ansichts-Controller erkennt, dass der erste Ansichts-Controller geöffnet wurde. Bitte beachten Sie auch die allgemeinere Diskussion hier: Unified UIViewController "wurde zur vordersten" Erkennung?
BEARBEITEN Ein Kommentar schlägt vor, dass dies
viewDidDisappear
eher sein sollte alsviewWillDisappear
.quelle
true
für die interaktive Wisch-Pop-Geste - vom linken Rand des Ansichts-Controllers - zurück, selbst wenn der Wisch sie nicht vollständig platzierte. Anstatt eswillDisappear
einzuchecken,didDisappear
funktioniert es also.Ich habe zwei Tage lang mit diesem Problem gespielt (oder gekämpft). IMO ist der beste Ansatz, einfach eine Erweiterungsklasse und ein Protokoll wie folgt zu erstellen:
Dies funktioniert, da jedes Mal, wenn ein View Controller geöffnet
UINavigationController
wird, ein AnrufnavigationBar:shouldPopItem:
eingeht. Dort erkennen wir, ob der Rücken gedrückt wurde oder nicht (jede andere Taste). Das einzige, was Sie tun müssen, ist das Protokoll in der Ansichtssteuerung zu implementieren, in der die Zurück-Taste gedrückt wird.Denken Sie daran, den View Controller manuell einzublenden
backButtonPressedSel
, wenn alles in Ordnung ist.Wenn Sie bereits Unterklassen erstellt
UINavigationViewController
und implementiertnavigationBar:shouldPopItem:
haben, machen Sie sich keine Sorgen, dies wird es nicht stören.Möglicherweise möchten Sie auch die Rückengeste deaktivieren.
quelle
Dies funktioniert für mich in iOS 9.3.x mit Swift:
Im Gegensatz zu anderen Lösungen hier scheint dies nicht unerwartet auszulösen.
quelle
Für die Aufzeichnung denke ich, dass dies mehr von dem ist, wonach er gesucht hat…
quelle
Wie
purrrminator
gesagt, die Antwort vonelitalon
ist nicht ganz richtig, dayour stuff
sie auch ausgeführt werden würde, wenn die Steuerung programmgesteuert geöffnet wird.Die Lösung, die ich bisher gefunden habe, ist nicht sehr schön, aber sie funktioniert für mich. Neben dem
elitalon
Gesagten überprüfe ich auch, ob ich programmgesteuert auftauche oder nicht:Sie müssen diese Eigenschaft zu Ihrem Controller hinzufügen und auf YES setzen, bevor Sie programmgesteuert einspringen:
Danke für Ihre Hilfe!
quelle
Am besten verwenden Sie die UINavigationController-Delegatmethoden
Auf diese Weise können Sie erkennen, welcher Controller den UINavigationController anzeigt.
quelle
Ich habe dieses Problem gelöst, indem ich der Navigationsleiste auf der linken Seite ein UIControl hinzugefügt habe.
Und Sie müssen daran denken, es zu entfernen, wenn die Ansicht verschwindet:
Das ist alles!
quelle
Sie können den Rückruf der Zurück-Taste wie folgt verwenden:
Für die schnelle Version können Sie so etwas wie im globalen Bereich tun
Unter einem haben Sie den Viewcontroller eingefügt, in dem Sie die Aktion der Zurück-Schaltfläche steuern möchten:
quelle
navigationShouldPopOnBackButton
das? Es ist nicht Teil der öffentlichen API.Wie Coli88 sagte, sollten Sie das UINavigationBarDelegate-Protokoll überprüfen.
Allgemeiner können Sie auch verwenden
- (void)viewWillDisapear:(BOOL)animated
, um benutzerdefinierte Arbeiten auszuführen, wenn die vom aktuell sichtbaren Ansichtscontroller beibehaltene Ansicht bald ausgeblendet wird. Leider würde dies die Push- und Pop-Fälle stören.quelle
Für Swift mit einem UINavigationController:
quelle
Die Antwort von 7ynk3r war sehr ähnlich zu dem, was ich am Ende verwendet habe, aber es waren einige Verbesserungen erforderlich:
quelle
Sie sollten das UINavigationBarDelegate-Protokoll auschecken . In diesem Fall möchten Sie möglicherweise die Methode navigationBar: shouldPopItem: verwenden.
quelle
self.navigationController.isMovingFromParentViewController funktioniert unter iOS8 und 9 nicht mehr. Ich verwende:
quelle
(SCHNELL)
Endlich gefundene Lösung. Die gesuchte Methode ist "willShowViewController", eine delegierte Methode von UINavigationController
quelle
MyViewController
zuPushedController
.