Ios 如何正确关闭';它以模态形式呈现?
在我的Ios 如何正确关闭';它以模态形式呈现?,ios,objective-c,swift,Ios,Objective C,Swift,在我的选项卡BarViewController中,我创建了一个UINavigationController,并将其显示为模式 var navController = UINavigationController() let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController self.presentVie
选项卡BarViewController
中,我创建了一个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
func swipedRightAndUserWantsToDismiss(){
self.navigationController.dismissViewControllerAnimated(false, completion:nil);
}
我建议您对
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)
}
控制器层次结构如下所示:
UITabViewController
|
| presents
|
UINavigationController
|
| contains view controllers
|
[root, MessagesViewController]
现在,如果您在MessagesViewController
中,那么它的navigationController
就是当前显示的控制器,您应该解除该控制器,但在MessagesViewController
上调用dislose
也应该起作用
但是,问题是,取消导航控制器不会删除其视图控制器。似乎您正在使用导航控制器(因为您使用的是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
}
navController不需要有成员。使用以下代码显示您的MessagesViewController
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let pesentingNavigationController = UINavigationController(rootViewController: messageVC)
self.presentViewController(pesentingNavigationController, animated: true, completion: nil)
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let MynavController = UINavigationController(rootViewController: messageVC)
self.presentViewController(MynavController, animated: true, completion: nil)
您的视图控制器代码将为
func swipedRightAndUserWantsToDismiss() {
self.navigationController.dismiss(animated: true, completion: nil)
}
如果只想显示viewcontroller,则可以直接显示该viewcontroller,而无需为特定的viewcontroller使用导航控制器
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let pesentingNavigationController = UINavigationController(rootViewController: messageVC)
self.presentViewController(pesentingNavigationController, animated: true, completion: nil)
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let MynavController = UINavigationController(rootViewController: messageVC)
self.presentViewController(MynavController, animated: true, completion: nil)
但是当我们需要从显示的视图控制器导航时,我们需要将视图控制器作为导航控制器的根视图。这样我们就可以从显示的视图控制器进行导航
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let pesentingNavigationController = UINavigationController(rootViewController: messageVC)
self.presentViewController(pesentingNavigationController, animated: true, completion: nil)
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let MynavController = UINavigationController(rootViewController: messageVC)
self.presentViewController(MynavController, animated: true, completion: nil)
从显示的视图控制器,您可以推送到另一个视图控制器,也可以从另一个视图控制器弹出
let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
let pesentingNavigationController = UINavigationController(rootViewController: messageVC)
self.presentViewController(pesentingNavigationController, animated: true, completion: nil)
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,则可以检查它
而swift版本可以检查这一点
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)
}
}
这就是我在目标C中解决问题的方法 您可以在self.navigationController本身上调用dismissViewControllerAnimated:NO 目标C
[self.navigationController dismissViewControllerAnimated:NO completion:nil];
Swift
self.navigationController.dismissViewControllerAnimated(false, completion: nil)
在Swift 3中,这是通过以下方式实现的:
self.navigationController?.dismiss(animated: true, completion: nil)
您可以使用以下命令正确地解除Swift 4中显示为模式的
UINavigationController
:
self.navigationController?.popViewController(animated: true)
谢谢如果堆栈中有许多视图控制器,但我的委托调用了
dismissViewControllerAnimated
,然后将其设置为nil,它会拒绝堆栈中的所有视图控制器吗?当您放弃对navController
的所有引用时,如果您不在其他地方保留其所有视图控制器,则其所有视图控制器都将被销毁。您也无法解除已设置为rootviewcontroller的视图控制器。因此,如果: