在我的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
答案 0 :(得分:23)
您的控制器层次结构如下所示:
UITabViewController
|
| presents
|
UINavigationController
|
| contains view controllers
|
[root, MessagesViewController]
现在,如果你在MessagesViewController
内,那么它的navigationController
就是正在呈现的那个,那就是你应该解雇的那个,但在dismiss
上呼叫MessagesViewController
也应该工作。
然而,问题是解雇导航控制器不会删除其视图控制器。您似乎正在使用导航控制器(因为您使用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
}
答案 1 :(得分:9)
试试这个
func swipedRightAndUserWantsToDismiss(){
self.navigationController.dismissViewControllerAnimated(false, completion:nil);
}
答案 2 :(得分:5)
如果你想只呈现一个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
的位置返回到原始视图控制器。
这是使用导航控制器执行presentViewController
的正确流程,以继续在视图控制器之间导航。
如果您不确定是否展示或推送了messageVC,那么您可以查看by this answer。
要检查的快速版本是
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)
}
}
答案 3 :(得分:4)
无需拥有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)
}
答案 4 :(得分:3)
在Swift 3中,这是通过以下方式实现的:
sdl00999 2.6.32.54-0.7.TDC.1.R.4-default #1 SMP 2012-04-19 16:07:40 +0200 x86_64 2016/11/15
-------------------------- analysis date: 2016/11/15 --------------------------
20:39:37 memtotal memfree buffers cached dirty slabmem swptotal swpfree _mem_
20:39:41 3700M 2386M 9M 353M 0M 121M 309M 302M
20:39:43 3700M 2385M 9M 353M 0M 121M 309M 302M
20:39:47 3700M 2385M 9M 353M 2M 121M 309M 302M
20:39:49 3700M 2385M 9M 353M 2M 121M 309M 302M
答案 5 :(得分:2)
我建议您为UINavigationController
使用其他初始化程序:
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let navController = UINavigationController(rootViewController: messageVC)
self.presentViewController(self.navController, animated: true, completion: nil)
要干扰,只需做
func swipedRightAndUserWantsToDismiss() {
self.navigationController.dismissViewControllerAnimated(true, completion: nil)
}
答案 6 :(得分:2)
这就是我在Objective C中解决问题的方法。
您可以在 self.navigationController 本身上调用 dismissViewControllerAnimated:NO 。
目标C
[self.navigationController dismissViewControllerAnimated:NO completion:nil];
<强>夫特强>
self.navigationController.dismissViewControllerAnimated(false, completion: nil)
答案 7 :(得分:1)
您可以使用以下命令正确消除在Swift 4中以模态形式显示的UINavigationController
:
self.navigationController?.popViewController(animated: true)