糟糕编程的后果:dismissViewController 与 popViewController
Posted
技术标签:
【中文标题】糟糕编程的后果:dismissViewController 与 popViewController【英文标题】:Consequences of Bad Programming: dismissViewController vs popViewController 【发布时间】:2013-10-29 20:22:36 【问题描述】:我了解dismissViewControllerAnimated:completion:
和popViewControllerAnimated:
之间的区别,如on Stack Overflow 和此处所述:
-dismissViewControllerAnimated:completion:
方法用于关闭 一个 UIViewController,由以下方法呈现:-presentViewController:animated:completion:
.使用了 UINavigationController 的
-popViewControllerAnimated:
方法 弹出由-pushViewController:animated
方法显示的控制器 UINavigationController.
我最近在我的应用程序中发现了一个错误,我在其中使用 [self dismissViewControllerAnimated:completion:]
关闭了一个在导航嵌入式应用程序中显示推送的 VC。当我应该吃披萨的时候,我炸了。我没有发现错误,因为一切正常,并且我的 VC 已按预期释放。
我的问题:将这两种方法混合起来会有什么后果?
【问题讨论】:
【参考方案1】:-presentViewController:animated:completion:
和 -pushViewController:animated:
表示不同的东西。前者说“呈现这个另一个视图控制器以替换你自己”。后者说“在你自己内部显示这个其他视图控制器,作为你正在控制的列表的一部分”。
所以这是关于谁被认为在过渡后负责显示。在前一种情况下,导航控制器放弃控制。在后者中,它保留了控制权。
前一个功能由UIViewController
提供。后者特定于UINavigationController
。
因为这两个动作完全不同,所以相反的动作是分开的。导航控制器可以捕获 dismissViewController:...
并检查命名控制器的呈现方式,分支到超类或 pop...
,但从设计和维护的角度来看,任务的合并将没有吸引力。
由于导航控制器不承诺将一件事映射到另一件事,并且UIViewController
不承诺如果您传递的控制器之前没有出现过任何特定行为,我认为您的字面意思是问题是:将这两件事混合在一起的结果是未定义的行为。
【讨论】:
谢谢。 -presentViewController:animated:completion 属于 UIViewController。如果你没有导航控制器,那么你根本不需要 -pushViewController:animated 吗?【参考方案2】:我不确定我是否能最好地解释这一点,但让我试试吧。
我现在正在开发一个基于标签的应用程序,每个标签都有自己的导航控制器。对于附加功能,我在导航栏分支上有一个 barbuttonitem 到一个模态视图(在某些情况下,一个模态到一个全新的导航控制器来控制特定功能路径的后台堆栈。
我将在任何导航控制器的根视图上调用dismissViewController,该导航控制器作为模态从另一个导航控制器启动。 (我希望这是有道理的。)
也许这样更好:
呈现视图控制器负责关闭它呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,它会自动将消息转发到呈现的视图控制器。
如果您连续呈现多个视图控制器,从而构建一个呈现的视图控制器堆栈,则在堆栈中较低的视图控制器上调用此方法会关闭其直接子视图控制器以及其上方的所有视图控制器堆栈上的孩子。发生这种情况时,只有最顶层的视图会以动画方式消失;任何中间视图控制器都简单地从堆栈中删除。最顶层的视图使用其模态转换样式被解除,这可能与堆栈中其他视图控制器使用的样式不同。
推送基于导航的视图控制器,并在需要时使用 popViewController。模态地引入任何从导航分支出来的东西,并在这种情况下根据需要使用dismissViewController。
【讨论】:
以上是关于糟糕编程的后果:dismissViewController 与 popViewController的主要内容,如果未能解决你的问题,请参考以下文章