除了控制器调用dismiss之外,能够解除整个视图控制器堆栈

时间:2017-07-25 21:45:56

标签: ios swift3 uiviewcontroller

我从UITabBarController(VC1)

开始

然后我在其上面显示UIViewController(VC2)并将其名为parentController的变量设置为self

let loginController = LoginController()
DispatchQueue.main.async {
    self.present(loginController, animated: false, completion: {
        // Once presented, set parentController = self
        loginController.parentController = self
    })
}

然后当用户点击"使用电子邮件登录按钮"

时,我继续在VC2之上呈现第三个UIViewController(VC3)
let withEmailController = WithEmailLoginController()
withEmailController.parentController = self
present(withEmailController, animated: true, completion: nil)

用电子邮件注册后,我会出示第四个UIViewController(VC4),以便用户可以选择他们的个人资料照片

let profilePicturePickerController = ProfilePicturePickerController()
profilePicturePickerController.parentController = self
present(profilePicturePickerController, animated: true, completion: nil)

用户选择了他们的个人资料图片后,我在VC4中调用此代码,试图从VC2中的函数中解除VC2,VC3和VC4:

parentController?.parentController?.handleDismiss()

VC2中的handleDismiss只是:

func handleDismiss() {
    // Progress MainTabBarController
    parentController?.progressWithLoggedInUser()
    // Dismiss the LoginController
    self.dismiss(animated: true) {
        // I do some things in here that aren't relevant to the question
    }
}

问题: 当从VC2调用属于名为handleDismiss的VC2的函数时,一切正常并且VC2被解除(VC3和VC4没有被解散,因为它们还没有被呈现)。但是,如果从VC4调用handleDismiss,则只有VC3和VC4被解除。 VC2仍然存在。根据我的理解,VC1,2,3,4都在同一个堆栈中。

我尝试了什么: 将所有present / dismiss命令放在DispatchQueue.main.async {code}中。 直接在VC4中调用parentController?.parentController?.dismiss(animated: true, completion: nil)具有相同的错误。从VC2调用handleDismiss()以确保其正常工作

我看过的其他地方: Dismiss more than one view controller simultaneouslyDismissing a Presented View Controller。我觉得设置这些parentController变量与使用presentingViewController

相同

1 个答案:

答案 0 :(得分:0)

好的结果是重新阅读苹果文档是一个好主意

答案:我现在的理解是,在dismiss上调用UIViewController可以做两件不同的事情,具体取决于控制器是否有任何子节点(控制器上面有控制器) )。如果您在最顶层的视图控制器上调用dismiss,即topController.dismiss(animated: true){code},它将按预期关闭顶级控制器。但是,如果在具有子节点的控制器上调用dismiss,它将关闭该控制器的所有子节点,但不会关闭该控制器本身。最顶级的孩子是唯一一个动画的孩子。

如果您在堆叠中呼叫解雇,则必须在您要解雇的孩子的父母上调用它:parentController.dismiss(animated: true){code}

已实施解决方案:函数handleDismiss()已移至VC1并修复了所有问题。