In meiner TabBarViewController
erstelle ich einen UINavigationController und präsentiere ihn als Modal.
var navController = UINavigationController()
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
self.presentViewController(self.navController, animated: false, completion: nil)
self.navController.pushViewController(messageVC, animated: false)
In meiner MessageViewController
möchte ich es so abweisen:
func swipedRightAndUserWantsToDismiss(){
if self == self.navigationController?.viewControllers[0] {
self.dismissViewControllerAnimated(true, completion: nil) //doesn't deinit
}else{
self.navigationController?.popViewControllerAnimated(true) //deinits correctly
}
}
deinit{
print("Deinit MessagesViewController")
}
Das Problem ist, dass mein MessagesViewController
deinit nicht aufgerufen wird, wenn ich zum Root-View-Controller komme und versuche, das untergeordnete Element und den UINavigationController zu entlassen. Etwas hält daran fest - höchstwahrscheinlich UINavigationController
Ihre Controller-Hierarchie sieht folgendermaßen aus:
UITabViewController
|
| presents
|
UINavigationController
|
| contains view controllers
|
[root, MessagesViewController]
Wenn Sie sich in MessagesViewController
befinden, dann ist dessen navigationController
diejenige, die präsentiert wird, und dies ist diejenige, die Sie abweisen sollten, aber der Aufruf von dismiss
für MessagesViewController
sollte ebenfalls funktionieren.
Das Problem ist jedoch, dass das Entfernen des Navigationscontrollers seine Ansichtscontroller nicht entfernt. Es scheint, als würden Sie sich an Ihren Navigationscontroller halten (da Sie ihn mit self.navController
präsentieren), so dass der Status angezeigt wird
UITabViewController
|
| self.navController holds a reference to
|
UINavigationController
|
| contains view controllers
|
[root, MessagesViewController]
Um MessagesViewController
richtig zu vernichten, müssen Sie entweder die navController
loslassen oder zum root gehen (wodurch MessagesViewController
aus der Ansichtshierarchie entfernt wird).
Die typische Lösung wäre, einen Verweis auf navController
nicht zu speichern. Sie können immer eine neue UINavigationController
erstellen, wenn Sie präsentieren . Eine andere Lösung ist die Verwendung eines Delegaten. Statt MessagesViewController
abzulehnen, rufen Sie den Moderator an, der angerufen wird
self.navController.dismiss(animated: true) {
self.navController = nil
}
Versuche dies
func swipedRightAndUserWantsToDismiss(){
self.navigationController.dismissViewControllerAnimated(false, completion:nil);
}
wenn Sie nur einen Viewcontroller präsentieren möchten, können Sie diesen Viewcontroller direkt präsentieren, ohne dass Sie einen Navigationscontroller für diesen Viewcontroller benötigen.
Wenn wir jedoch von diesem präsentierten View-Controller aus navigieren müssen, müssen wir einen View-Controller als Stammansicht des Navigationscontrollers verwenden. Damit wir von diesem präsentierten View-Controller aus navigieren können.
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let MynavController = UINavigationController(rootViewController: messageVC)
self.presentViewController(MynavController, animated: true, completion: nil)
und von diesem dargestellten Ansichtscontroller aus können Sie auf einen anderen Ansichtscontroller drücken und auch von einem anderen Ansichtscontroller aus springen.
Und vom vorgestellten View Controller, hier messageVC
, müssen wir das als verwerfen
func swipedRightAndUserWantsToDismiss() {
self.dismiss(animated: true, completion: nil)
}
dies wird messageVC
erfolgreich verwerfen und zu Origin viewcontroller zurückkehren, von wo aus wir messageVC
vorgestellt haben.
Dies ist der richtige Ablauf, um presentViewController
mit dem Navigationscontroller auszuführen, um die Navigation zwischen den Viewcontrollern fortzusetzen.
Und wenn Sie sich nicht sicher sind, ob messageVC angezeigt oder gepusht wird, können Sie dies überprüfen anhand dieser Antwort .
Und die Swift-Version soll das überprüfen
func isModal() -> Bool {
if((self.presentingViewController) != nil) {
return true
}
if(self.presentingViewController?.presentedViewController == self) {
return true
}
if(self.navigationController?.presentingViewController?.presentedViewController == self.navigationController) {
return true
}
if((self.tabBarController?.presentingViewController?.isKindOfClass(UITabBarController)) != nil) {
return true
}
return false
}
Unsere abschließende Klage ist also wie folgt
func swipedRightAndUserWantsToDismiss() {
if self.isModal() == true {
self.dismiss(animated: true, completion: nil)
}
else {
self.navigationController?.popViewControllerAnimated(true)
}
}
Kein Mitglied für navController. Verwenden Sie den folgenden Code, um Ihren MessagesViewController zu präsentieren.
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let pesentingNavigationController = UINavigationController(rootViewController: messageVC)
self.presentViewController(pesentingNavigationController, animated: true, completion: nil)
Sie werden den Code für den Ansichts-Controller verwerfen
func swipedRightAndUserWantsToDismiss() {
self.navigationController.dismiss(animated: true, completion: nil)
}
In Swift 3 wird dies erreicht mit:
self.navigationController?.dismiss(animated: true, completion: nil)
Ich schlage vor, dass Sie den anderen Initializer für Ihre UINavigationController
verwenden:
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let navController = UINavigationController(rootViewController: messageVC)
self.presentViewController(self.navController, animated: true, completion: nil)
Zum Ablegen einfach tun
func swipedRightAndUserWantsToDismiss() {
self.navigationController.dismissViewControllerAnimated(true, completion: nil)
}
So löse ich das Problem in Ziel C.
Sie können dismissViewControllerAnimated aufrufen: NO auf Ihrem self.navigationController sich selbst.
Ziel c
[self.navigationController dismissViewControllerAnimated:NO completion:nil];
Swift
self.navigationController.dismissViewControllerAnimated(false, completion: nil)
Sie können Folgendes verwenden, um eine UINavigationController
, die in Swift 4 als Modal dargestellt wird, richtig zu verwerfen:
self.navigationController?.popViewController(animated: true)