Swift - 如何关闭所有视图控制器以返回到root

Byo*_*oth 43 navigation uiviewcontroller ios swift

我希望我的应用程序可以在每次用户需要时转到第一个视图控制器.

因此,我想创建一个函数来关闭所有视图控制器,无论它是在推送控制器中推送还是以模态方式呈现或打开任何方法.

我尝试了各种方法,但我当然没有解雇所有的视图控制器.有一个简单的方法吗?

Age*_*ith 52

试试这个 :

self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

它应该关闭根视图控制器上方的所有视图控制器.

如果这不起作用,你可以通过运行像这样的while循环手动执行此操作.

func dismissViewControllers() {

    guard let vc = self.presentingViewController else { return }

    while (vc.presentingViewController != nil) {
        vc.dismiss(animated: true, completion: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

它将解除所有viewControllers,直到它有一个presentationController.

编辑:如果你想解雇/弹出推送的ViewControllers你可以使用

self.navigationController?.popToRootViewController(animated: true)
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

  • 谢谢。它完全适用于所有提供的视图控制器,但不适用于推入视图控制器(如果根视图控制器是导航控制器)。所以我也一起总结了使用popToRootViewController的其他观点,并解决了:) (2认同)

San*_*ill 23

如果您使用的是导航,则可以使用第一个,或者如果您以模态方式呈现,则可以使用第二个:

用于导航

self.navigationController?.popToRootViewController(animated: true)
Run Code Online (Sandbox Code Playgroud)

用于呈现模态

self.view.window!.rootViewController?.dismissViewControllerAnimated(false, completion: nil)
Run Code Online (Sandbox Code Playgroud)


Sye*_*bas 14

如果出席,只需要求你rootViewController解雇ViewController.

if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
   appDelegate.window?.rootViewController?.dismiss(animated: true, completion: nil)
   (appDelegate.window?.rootViewController as? UINavigationController)?.popToRootViewController(animated: true)
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。它完全适用于所有提供的视图控制器,但不适用于推入视图控制器(如果根视图控制器是导航控制器)。所以我也一起总结了使用popToRootViewController的其他观点,并解决了:) (2认同)

Pat*_*ush 13

大家好,这是Swift-4的答案。

要返回到根视图控制器,您只需调用一行代码即可完成工作。

 self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

如果您有启动屏幕,然后是登录屏幕,并且想要进入登录屏幕,则只需在上面的代码中附加presentedviewcontroller

self.view.window?.rootViewController?.presentedViewController!.dismiss(animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)


Sha*_*ank 11

返回初始视图控制器的策略可能会有所不同,具体取决于视图控制器的堆叠情况。

可能有多种情况,根据您的情况,您可以决定哪种方法是最好的。

场景1

  • 导航控制器设置为根视图控制器
  • 导航控制器将视图控制器 A 设置为根
  • 导航控制器推动视图控制器 B
  • 导航控制器推动视图控制器 C

这是一个简单的场景,navigationController?.popToRootViewController(animated:true)可以在任何视图控制器上工作并返回到视图控制器 A

场景2

  • 导航控制器设置为根视图控制器
  • 导航控制器将视图控制器 A 设置为根
  • 视图控制器 A 呈现视图控制器 B
  • 视图控制器 B 呈现视图控制器 C

这种情况可以通过上面的答案来解决 self?.view.window?.rootViewController.dismiss(animated: true),并将带您回到视图控制器 A

场景3

  • 导航控制器 1 设置为根视图控制器
  • 导航控制器 1 将视图控制器 A 设置为根
  • 导航控制器 1 推动视图控制器 B
  • 视图控制器 B 呈现导航控制器 2
  • 导航控制器 2 将视图控制器 D 设置为根
  • 导航控制器 2 推动视图控制器 E

现在想象一下您需要从视图控制器 E 一路返回到 A

这次使用上面的 2 个答案将无法解决您的问题,因为如果导航控制器不在屏幕上,则无法弹出到根目录。

您可能会尝试添加计时器和侦听器来消除视图控制器,然后弹出可以工作的功能,我认为上面有一个带有函数的答案dismissPopAllViewViewControllers- 我注意到这会导致异常行为并带有此警告Unbalanced calls to begin/end appearance transitions for

我相信解决这种情况你可以做的是

  • 首先从导航控制器本身呈现模式视图控制器
  • 现在你可以更好地控制做你想做的事

所以我首先将上面的架构改为这个架构:

  • 导航控制器1设置为根视图控制器(同上)
  • 导航控制器 1 将视图控制器 A 设置为根(相同)
  • 导航控制器 1 推动视图控制器 B(相同)
  • 导航控制器 1 呈现导航控制器 2(更改)
  • 导航控制器 2 将视图控制器 D 设置为根(相同)
  • 导航控制器 2 推动视图控制器 E(相同)

现在从视图控制器 E,如果添加以下内容:

let rootViewController = self?.view.window?.rootViewController as? UINavigationController

rootViewController?.setViewControllers([rootViewController!.viewControllers.first!], 
animated: false)

rootViewController?.dismiss(animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

您将一路回到视图控制器 A,没有任何警告

您可以根据您的要求进行调整,但这是如何重置复杂视图控制器层次结构的概念。


Far*_*med 6

使用此代码关闭呈现的视图控制器并弹出导航 rootviewcontroller swift 4

// MARK:- Dismiss and Pop ViewControllers
func dismissPopAllViewViewControllers() {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        appDelegate.window?.rootViewController?.dismiss(animated: true, completion: nil)
        (appDelegate.window?.rootViewController as? UINavigationController)?.popToRootViewController(animated: true)
    }
}
Run Code Online (Sandbox Code Playgroud)


Mak*_* BK 5

斯威夫特 5.4:

self.navigationController?.popToRootViewController(animated: true)
Run Code Online (Sandbox Code Playgroud)