父视图控制器未解除
Posted
技术标签:
【中文标题】父视图控制器未解除【英文标题】:Parent view controller not dismissed 【发布时间】:2017-02-27 18:29:00 【问题描述】:presentViewController
function 有问题。
我有一个登录菜单 (A) 和一个显示登录表单的按钮 (B)。成功登录后,我会使用self.presentViewController
(C) 呈现第三个视图。
登录菜单 (A) -> 登录表单 (B) -> 内容 (C)
它的工作,我可以呈现第三个视图 (C) 但登录菜单 (A) 始终可见(我可以在 UI 调试模式中看到它)。
那么,如何关闭A ViewController?
【问题讨论】:
登录后在 ->content (C) 中关闭当前视图控制器 你试过 self.navigationController 解散吗?? 这就是 presentViewController 的工作方式。如果您从 A 呈现 B,这并不意味着它会关闭 A。如果您想将“内容”设置为 rootController,那么您必须更改 window.rootviewcontroller = yourviewcontroller。 您可能需要将层次结构的顺序更改为最合乎逻辑的顺序,例如Content (A) ➜ Login Menu (B) ➜ Login Form (C),所以当您关闭登录表单和视图时,它回退到应有的内容 (A)。 ***.com/questions/19962276/… 参考最佳实践 【参考方案1】:presentViewController
,以模态方式呈现视图控制器。换句话说,在当前视图控制器的内容上,当前视图控制器不会被释放。
为您的示例使用以下代码:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: <Identifier as in Storyboard of C>)
(UIApplication.shared.delegate as! AppDelegate).window?.rootViewController = vc
如果您想包含一个过渡,您可以将最后一行替换为以下内容:
UIView.transition(from: currentRootViewController!.view, to: vc.view, duration: 0.8, options: .transitionCrossDissolve, completion: (_) in
(UIApplication.shared.delegate as! AppDelegate).window?.rootViewController = vc
)
【讨论】:
@YoannLth :这是您可以更改根控制器的方式 OP 的帖子似乎是XY Problem,因此您需要为他解决问题 X,而不是为问题 Y 提供过于复杂的解决方案。 我试过这个答案@Wolverine,但它没有用。我用一个肮脏的hack解决了这个问题:我用self.view.window!.rootViewController?.dismissViewControllerAnimated(false, completion: nil)
关闭了所有视图控制器,它返回到应用程序入口点,这是一个检查用户是否登录的ViewController。
@YoannLth,我按照holex 的建议简化了解决方案。我认为我对你的解释的问题在于我指向了 initialVC,而你的 C 可能不是你的 initialVC。【参考方案2】:
我认为本教程有你的答案https://www.youtube.com/watch?v=WIaRs2d6Xm0
【讨论】:
【参考方案3】:如果我们考虑 presentVieController 机制,这不是问题或错误。不过,如果您觉得您不希望之前的控制器保留在 Hierarchy 中,那么您必须更改流程。
目前您的流程是:
A -> RootViewController。 B -> 登录屏幕 C -> 容器
我建议参考以下答案以获得最佳实践。
Best practices for Storyboard login screen, handling clearing of data upon logout
如果您提出处理流程的想法,您可以解决您的问题。这是我的建议
建议:
-
您将C设置为rootController,在C的ViewDidLoad中,检查天气用户是否登录,如果用户未登录,则可以显示A ,然后您可以从那里呈现 B。成功登录后,您可以关闭 A 和 B 并根据登录的用户值刷新您的 rootController C。
要关闭多个视图控制器,您可以尝试以下代码
-(void)dismissModalStack
UIViewController *vc = self.presentingViewController;
while (vc.presentingViewController)
vc = vc.presentingViewController;
[vc dismissViewControllerAnimated:YES completion:NULL];
-
也可以使用ContainerView机制,将C设置为rootController,在C中,取一个ContainerView 可以在其中显示A和B,登录后可以删除它们并刷新C。
希望对你有帮助!
【讨论】:
以上是关于父视图控制器未解除的主要内容,如果未能解决你的问题,请参考以下文章
不允许在解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为