Wenn Sie einen Modal View Controller mit schließen dismissViewController
, besteht die Möglichkeit, einen Abschlussblock bereitzustellen. Gibt es ein ähnliches Äquivalent für popViewController
?
Das Vervollständigungsargument ist sehr praktisch. Zum Beispiel kann ich damit das Entfernen einer Zeile aus einer Tabellenansicht verzögern, bis das Modal nicht mehr auf dem Bildschirm angezeigt wird, sodass der Benutzer die Zeilenanimation sehen kann. Bei der Rückkehr von einem Push-View-Controller möchte ich die gleiche Gelegenheit.
Ich habe versucht, popViewController
einen UIView
Animationsblock zu platzieren, in dem ich Zugriff auf einen Abschlussblock habe. Dies führt jedoch zu einigen unerwünschten Nebenwirkungen auf die Ansicht, auf die zugegriffen wird.
Welche Problemumgehungen gibt es, wenn keine solche Methode verfügbar ist?
quelle
Antworten:
Ich weiß, dass eine Antwort vor über zwei Jahren akzeptiert wurde, diese Antwort ist jedoch unvollständig.
Dies ist technisch korrekt, da die
UINavigationController
API hierfür keine Optionen bietet. Mit dem CoreAnimation-Framework können Sie der zugrunde liegenden Animation jedoch einen Abschlussblock hinzufügen:Der Abschlussblock wird aufgerufen, sobald die von
popViewControllerAnimated:
Ende verwendete Animation beendet ist. Diese Funktionalität ist seit iOS 4 verfügbar.quelle
extension UINavigationController { func popViewControllerWithHandler(handler: ()->()) { CATransaction.begin() CATransaction.setCompletionBlock(handler) self.popViewControllerAnimated(true) CATransaction.commit() } }
Für iOS9 SWIFT-Version - funktioniert wie ein Zauber (wurde nicht für frühere Versionen getestet). Basierend auf dieser Antwort
quelle
Ich habe eine
Swift
Version mit Erweiterungen mit der Antwort @JorisKluivers erstellt .Dies ruft einen Abschluss ab, nachdem die Animation für
push
und abgeschlossen wurdepop
.quelle
popViewController
oder aufgerufenpushViewController
, aber wenn Sie überprüfen, was der topViewController direkt danach ist, werden Sie feststellen, dass es immer noch der alte ist, genau wiepop
oderpush
nie passiert ...SWIFT 4.1
quelle
Ich hatte das gleiche Problem. Und weil ich es mehrmals und innerhalb von Ketten von Abschlussblöcken verwenden musste, habe ich diese generische Lösung in einer UINavigationController-Unterklasse erstellt:
Vorausgesetzt
und
und
quelle
Es gibt keine Möglichkeit, das zu tun, was Sie möchten. Das heißt, es gibt keine Methode mit einem Abschlussblock zum Löschen eines Ansichtscontrollers von einem Navigationsstapel.
Was ich tun würde, ist die Logik einzubauen
viewDidAppear
. Dies wird aufgerufen, wenn die Ansicht nicht mehr auf dem Bildschirm angezeigt wird. Es wird für alle verschiedenen Szenarien des View Controllers aufgerufen, aber das sollte in Ordnung sein.Oder Sie könnten die
UINavigationControllerDelegate
Methode verwenden,navigationController:didShowViewController:animated:
um etwas Ähnliches zu tun. Dies wird aufgerufen, wenn der Navigations-Controller einen Ansichts-Controller nicht mehr gedrückt oder geöffnet hat.quelle
dismissViewController
. Vielleicht kommt es zupopViewController
. Datei ein Radar :-).-dismissViewController:animated:completionBlock:
, aber Sie können die Animation über den Delegaten des Navigationscontrollers abrufen. Nachdem die Animation abgeschlossen ist,-navigationController:didShowViewController:animated:
wird der Delegierte aufgerufen und Sie können genau dort tun, was Sie benötigen.Arbeiten mit oder ohne Animation richtig und beinhaltet auch
popToRootViewController
:quelle
completion()
Async aufrufen ?completion
niemals auf demselben Runloop ausgeführt wird. Dies garantiert, dasscompletion
niemals auf demselben Runloop ausgeführt wird, wenn nicht animiert wird. Es ist besser, diese Art von Inkonsistenz nicht zu haben.Basierend auf der Antwort von @ HotJard, wenn Sie nur ein paar Codezeilen benötigen. Schnell und einfach.
Swift 4 :
quelle
Für 2018 ...
wenn du das hast ...
und Sie möchten eine Vervollständigung hinzufügen ...
so einfach ist das
Praktischer Tipp ...
Es ist das gleiche Angebot für den praktischen
popToViewController
Anruf.Eine typische Sache ist, dass Sie einen Onboarding-Stapel von zig Bildschirmen haben. Wenn Sie fertig sind, kehren Sie vollständig zu Ihrem "Basis" -Bildschirm zurück und starten schließlich die App.
Also im "Basis" -Bildschirm, um "den ganzen Weg zurück" zu gehen,
popToViewController(self
quelle
Der Abschlussblock wird aufgerufen, nachdem die viewDidDisappear-Methode auf dem dargestellten Ansichtscontroller aufgerufen wurde. Daher sollte das Einfügen von Code in die viewDidDisappear-Methode des Popup-Ansichtscontrollers genauso funktionieren wie ein Abschlussblock.
quelle
Swift 3-Antwort dank dieser Antwort: https://stackoverflow.com/a/28232570/3412567
quelle
Swift 4-Version mit optionalem viewController-Parameter, um zu einem bestimmten zu wechseln.
quelle
Die Swift 4- Version wurde basierend auf dieser Antwort bereinigt .
quelle
Es gibt einen Pod namens UINavigationControllerWithCompletionBlock, der die Unterstützung eines Abschlussblocks beim Drücken und Poppen eines UINavigationControllers hinzufügt.
quelle
2020 Swift 5.1 Weg
Diese Lösung garantiert, dass der Abschluss ausgeführt wird, nachdem popViewController vollständig abgeschlossen ist. Sie können es testen, indem Sie einen weiteren Vorgang auf dem NavigationController ausführen: In allen anderen oben genannten Lösungen ist der UINavigationController noch mit dem popViewController-Vorgang beschäftigt und antwortet nicht.
quelle
Der Vollständigkeit halber habe ich eine Objective-C-Kategorie einsatzbereit gemacht:
quelle
Genau das habe ich mit einem Block präzise erreicht. Ich wollte, dass mein Controller für abgerufene Ergebnisse die von der modalen Ansicht hinzugefügte Zeile nur anzeigt, wenn sie den Bildschirm vollständig verlassen hat, damit der Benutzer die Änderung sehen kann. In Vorbereitung auf den Übergang, der für die Anzeige des Modal View Controllers verantwortlich ist, setze ich den Block, den ich ausführen möchte, wenn das Modal verschwindet. Und im Modal View Controller überschreibe ich viewDidDissapear und rufe dann den Block auf. Ich beginne einfach mit Updates, wenn das Modal angezeigt wird, und beende Updates, wenn es verschwindet. Dies liegt jedoch daran, dass ich einen NSFetchedResultsController verwende. Sie können jedoch innerhalb des Blocks tun, was Sie möchten.
quelle
Verwenden Sie die nächste Erweiterung Ihres Codes: (Swift 4)
quelle