objective-c - 如何一次关闭 3 个模态视图 Controller ?

标签 objective-c uiviewcontroller modalviewcontroller

我有一个应用程序,它有一个初始登录屏幕,然后当用户想要注册时,他们会看到一个以模态方式显示的三个 View Controller 的注册表单。当用户在第三个屏幕上完成表单时(通过按“完成”按钮),我希望将用户带回初始登录屏幕。

我试过在第三个 View Controller 中这样做:

[self dismissViewControllerAnimated:NO completion:nil]
[self.presentingViewController dismissViewControllerAnimated:NO completion:nil]
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:NO completion:nil]

但是它只关闭了两个 View Controller ,而不是全部 3 个。为什么会这样?

最佳答案

正如其他人所指出的,从用户体验的角度来看,有更优雅/更高效/更简单的方法可以实现类似的结果:通过导航 Controller 、页面 View Controller 或其他容器。

简短/快速回答:您需要在呈现 View Controller 链中更进一步,因为解散请求需要发送到正在呈现的 Controller ,而不是正在呈现的 Controller 。并且您可以仅向该 Controller 发送解除请求,它将负责从堆栈中弹出子 Controller 。

UIViewController *ctrl = self.presentingViewController.presentingViewController.presentingViewController;
[ctrl dismissViewControllerAnimated:NO completion:nil]

为了解释原因,并希望帮助其他人更好地理解 iOS 中的 Controller 呈现逻辑,您可以在下面找到更多详细信息。

让我们从Apple documentation开始在 dismissViewControllerAnimated:completion:

Dismisses the view controller that was presented modally by the view controller.

The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.

因此 [self dismissViewControllerAnimated:NO completion:nil] 只是将请求转发给 self.presentingViewController。这意味着前两行具有相同的效果(实际上第二行什么也没做,因为在第一行执行后没有呈现 Controller )。

这就是为什么您对 View Controller 的解雇只对前 2 个起作用。您应该从 self.presentingViewController 开始,然后沿着呈现 View Controller 链前进。但这不是很优雅,如果稍后 View Controller 的层次结构发生变化,可能会导致问题。

继续阅读文档,我们偶然发现了这一点:

If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack.

因此您无需调用 dismissViewControllerAnimated:completion: 三次,在您想要返回的 Controller 上调用一次就足够了。在这一点上,传递对该 Controller 的引用比在 View Controller 堆栈中导航更可靠。

文档中有一些更有用的细节,例如关于一次关闭多个 Controller 时适用的转换。

我建议您通读整个文档,不仅针对此方法,还针对您在应用程序中使用的所有方法/类。您可能会发现一些能让您的生活更轻松的事情。

如果您没有时间阅读 Apple 关于 UIKit 的所有文档,您可以在遇到问题时阅读它,例如在这种情况下 dismissViewControllerAnimated:completion: not working as you以为会。

作为结束语,您的方法存在一些更微妙的问题,因为实际解雇发生在另一个运行循环周期中,因为它可能会生成控制台警告并且不会按预期运行。这就是为什么应该在完成 block 中完成有关呈现/关闭其他 Controller 的进一步操作,以更改 UIKit 以完成更新其内部状态。

关于objective-c - 如何一次关闭 3 个模态视图 Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34557098/

相关文章:

iphone - 显示模态视图 Controller 时设备旋转

ios - 在 View Controller 生命周期中何时呈现 UIImagePickerController?

ios - Facebook 以小型模态视图登录

ios - 呈现小型 Modal VIewController Objective C

ios - Facebook SDK 使用 Graph API 1.0 版

ios - 如何解决JSON字典

objective-c - 在突出显示/选择单元格时,在自定义 UITableViewCell 中为 UITextField 提供正确的文本颜色

iphone - 如何使用 UITouches 移动 CGRect?

ios - viewController 内的 tableview 中没有显示任何信息

ios - 从后台进入前台时无法显示admob插页式广告