错误编程的后果:dismissViewController vs popViewController

时间:2013-10-29 20:22:37

标签: ios cocoa-touch uiviewcontroller navigationcontroller

我理解dismissViewControllerAnimated:completion:popViewControllerAnimated:之间的区别,如on Stack Overflow所描述的那样:

  

-dismissViewControllerAnimated:completion:方法用于解雇   一个UIViewController,由该方法呈现:   -presentViewController:animated:completion:

     使用了

-popViewControllerAnimated: UINavigationController方法   弹出-pushViewController:animated方法显示的控制器   UINavigationController的。

我最近在我的应用程序中发现了一个错误,我使用[self dismissViewControllerAnimated:completion:]来解除在导航嵌入式应用程序中推送的VC。当我应该吃比萨饼的时候,法国人炒了。我没有发现错误,因为一切正常,我的VC按预期被解除分配。

我的问题:混合使用这两种方法有什么后果?

2 个答案:

答案 0 :(得分:17)

-presentViewController:animated:completion:-pushViewController:animated:意味着不同的事情。前者说“提出另一个视图控制器以取代自己”。后者说“在你自己内部显示另一个视图控制器,作为你正在控制的列表的一部分”。

所以这是关于过渡后谁被认为负责显示器的问题。在前一种情况下,导航控制器放弃控制。在后者中它保留了控制权。

前一项功能由UIViewController提供。后者特定于UINavigationController

因为这两个动作完全不同,所以相反的动作是分开的。导航控制器可以捕获dismissViewController:...并检查命名控制器的呈现方式,分支到超类或pop...,但从设计和维护的角度来看,任务的混合将没有吸引力。

由于导航控制器不承诺将一件事映射到另一件事,并且UIViewController不承诺任何特定行为,如果您传递的控制器之前没有呈现过,我认为字面答案对你的问题是:混合这两件事的结果是未定义的行为。

答案 1 :(得分:1)

我不确定我是否可以解释这个我想要的最好但让我试试。

我正在开发一个基于Tab的应用程序,每个选项卡都有自己的导航控制器。对于侧面特征,我在导航栏上有一个barbuttonitem到一个模态视图(在某些情况下是一个全新导航控制器的模态,用于控制特定功能路径的后台。

我将在我作为模态启动的任何导航控制器的根视图上调用dismissViewController。 (我希望这是有道理的。)

也许这更好:

呈现视图控制器负责解除它所呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,它会自动将消息转发给呈现视图控制器。

如果您连续呈现多个视图控制器,从而构建一堆呈现的视图控制器,则在堆栈中较低的视图控制器上调用此方法会解除其直接子视图控制器和上面的所有视图控制器孩子在堆栈上。发生这种情况时,只有最顶层的视图以动画方式被删除;任何中间视图控制器都可以从堆栈中删除。最顶层的视图使用其模态过渡样式被忽略,这可能与堆栈中较低的其他视图控制器使用的样式不同。

推送基于导航的视图控制器,并在需要时使用popViewController。模拟引入从导航中分支出来的任何内容,并根据需要使用dismissViewController。