[英]How to correctly dismiss a UINavigationController that's presented as a modal?
在我的TabBarViewController
,我創建了一個UINavigationController並將其作為模態呈現。
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)
在我的MessageViewController
,這是我想要解雇它的方式:
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")
}
問題是,當我到達根視圖控制器並嘗試關閉子和UINavigationController時,我的MessagesViewController
deinit不會被調用。 有些東西正在堅持下去 - 很可能是UINavigationController
您的控制器層次結構如下所示:
UITabViewController
|
| presents
|
UINavigationController
|
| contains view controllers
|
[root, MessagesViewController]
現在,如果你在MessagesViewController
里面,那么它的navigationController
就是那個正在呈現的那個,你應該解雇的那個但是在MessagesViewController
上調用dismiss
也應該有效。
但是,問題是解雇導航控制器不會刪除其視圖控制器。 看起來你正在堅持你的導航控制器(因為你使用self.navController
呈現它)所以狀態將成為
UITabViewController
|
| self.navController holds a reference to
|
UINavigationController
|
| contains view controllers
|
[root, MessagesViewController]
要正確銷毀MessagesViewController
您必須放棄navController
否則必須彈出到root(從而從視圖層次結構中刪除MessagesViewController
)。
典型的解決方案是根本不保存對navController
的引用。 您可以在演示時始終創建新的UINavigationController
。 另一個解決方案是使用委托 - 而不是從MessagesViewController
內部解雇,讓它回調給演示者,這將調用
self.navController.dismiss(animated: true) {
self.navController = nil
}
嘗試這個
func swipedRightAndUserWantsToDismiss(){
self.navigationController.dismissViewControllerAnimated(false, completion:nil);
}
如果你只想呈現一個viewcontroller,那么你可以直接呈現那個viewcontroller而不需要為那個特定的viewcontroller帶一個導航控制器。
但是當我們需要從顯示的視圖控制器導航時,我們需要將視圖控制器作為導航控制器的根視圖。 這樣我們就可以從那個呈現的視圖控制器中導航。
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let MynavController = UINavigationController(rootViewController: messageVC)
self.presentViewController(MynavController, animated: true, completion: nil)
從該呈現的視圖控制器,您可以推送到另一個視圖控制器,並從另一個視圖控制器彈出。
從呈現的視圖控制器,這里是messageVC
,我們不得不將其視為
func swipedRightAndUserWantsToDismiss() {
self.dismiss(animated: true, completion: nil)
}
這將成功解除messageVC
並從我們提供messageVC
地方返回到origin viewcontroller。
這是使用導航控制器執行presentViewController
的正確流程,以繼續視圖控制器之間的導航。
如果您不確定是否呈現或推送了messageVC,那么您可以通過此答案進行檢查。
而快速版本檢查是
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
}
所以我們最后解雇的行動就像是
func swipedRightAndUserWantsToDismiss() {
if self.isModal() == true {
self.dismiss(animated: true, completion: nil)
}
else {
self.navigationController?.popViewControllerAnimated(true)
}
}
無需擁有navController的成員。 使用以下代碼顯示您的MessagesViewController。
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let pesentingNavigationController = UINavigationController(rootViewController: messageVC)
self.presentViewController(pesentingNavigationController, animated: true, completion: nil)
您的解雇視圖控制器代碼將是
func swipedRightAndUserWantsToDismiss() {
self.navigationController.dismiss(animated: true, completion: nil)
}
我建議你為你的UINavigationController
使用另一個初始化器:
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let navController = UINavigationController(rootViewController: messageVC)
self.presentViewController(self.navController, animated: true, completion: nil)
為了dimiss,干脆做
func swipedRightAndUserWantsToDismiss() {
self.navigationController.dismissViewControllerAnimated(true, completion: nil)
}
這就是我在Objective C中解決問題的方法。
您可以在self.navigationController本身上調用dismissViewControllerAnimated:NO 。
目標C.
[self.navigationController dismissViewControllerAnimated:NO completion:nil];
迅速
self.navigationController.dismissViewControllerAnimated(false, completion: nil)
在Swift 3中,這是通過以下方式實現的:
self.navigationController?.dismiss(animated: true, completion: nil)
您可以使用以下命令正確關閉在Swift 4中作為模式呈現的UINavigationController
:
self.navigationController?.popViewController(animated: true)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.