一次关闭两个UIViewController而不使用动画

时间:2018-11-29 10:27:01

标签: ios swift uiviewcontroller

我有一堆UIViewController,例如A -> B -> C。我想从C返回到控制器A。我正在使用以下代码进行操作:

DispatchQueue.global(qos: .background).sync {
// Background Thread
DispatchQueue.main.async {
    self.presentingViewController?.presentingViewController?.dismiss(animated: false, completion: {
    })}
}

它可以工作,但是控制器B在屏幕上可以看到,尽管我将动画设置为false。如何在不显示中间一个(B)的情况下关闭两个UIViewController?

P.S:我不能直接从根控制器中解雇,也不能使用UINavigationController

我搜索了社区,但找不到有关动画的任何内容。

Dismiss more than one view controller simultaneously

2 个答案:

答案 0 :(得分:2)

尝试一下。

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)

创建了一个这样的示例情节提要

enter image description here

黄色视图控制器的类型为ViewController,按钮操作如下所示

@IBAction func Pressed(_ sender: Any) {
    self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}

输出

enter image description here

答案 1 :(得分:0)

在创建C控制器之前,我创建了解雇B控制器的示例。你可以试试看。

    let bController = ViewController()
    let cController = ViewController()

    aController.present(bController, animated: true) {

        DispatchQueue.main.asyncAfter(wallDeadline: .now()+2, execute: {

            let presentingVC = bController.presentingViewController

            bController.dismiss(animated: false, completion: {

                presentingVC?.present(cController, animated: true, completion: nil)

            })
        })

    }

但是我认为使用导航控制器的解决方案将是最好的选择。例如,您可以仅将B控制器放入导航控制器中->将navController呈现到A控制器上->然后在navController内显示C->然后从C控制器中删除整个navController->然后您将再次看到A控制器。也要考虑解决方案。

另一种解决方案

我已经检查了另一种解决方案。 这里的扩展名应该可以解决您的问题。

extension UIViewController {

    func dissmissViewController(toViewController: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
        self.dismiss(animated: flag, completion: completion)
        self.view.window?.insertSubview(toViewController.view, at: 0)
        dissmissAllPresentedControllers(from: toViewController)
        if toViewController.presentedViewController != self {
            toViewController.presentedViewController?.dismiss(animated: false, completion: nil)
        }
    }

    private func dissmissAllPresentedControllers(from rootController: UIViewController) {
        if let controller = rootController.presentedViewController, controller != self {
            controller.view.isHidden = true
            dissmissAllPresentedControllers(from: controller)
        }
    }

}

用法

let rootController = self.presentingViewController!.presentingViewController! //Pointer to controller which should be shown after you dismiss current controller
self.dissmissViewController(toViewController: rootController, animated: true) 

//所有以前的控制器也将被解雇,    //,但您看不到它们,因为我将它们隐藏并添加到当前视图的窗口中。

但是我认为解决方案可能无法涵盖您的所有情况。如果您的控制器未在整个屏幕上显示,可能会出现问题,因为类似的事情,因为当我模拟这种过渡时,我没有考虑到事实,因此您可能需要针对特定​​情况来适应扩展。 / p>