UIWindow setRootViewController不清除现有层次结构

问题描述 投票:6回答:3

在我的应用中,我以编程方式根据用户操作更改根视图控制器,例如登录/注销功能。

在iOS 8中 - 我注意到一个奇怪的问题。即使在窗口上设置rootViewController之后,旧的层次结构仍然存在。我只是通过捕获视图层次结构来验证它。

- (void) logout{
     [self.window setRootViewController:[self loadLoginView]];
}

-(UIViewController *) loadLoginView{
      WelcomeScreenVC *wsVC;
      wsVC = [[WelcomeScreenVC alloc] initWithNibName:@"WelcomeScreenVC" bundle:nil];
      UINavigationController *onboardingVC = [[UINavigationController alloc]initWithRootViewController:wsVC];
      return onboardingVC;
 }

即使在执行此行代码后,旧的登录视图层次结构仍然存在。如果有人能够提出幕后发生的事情,我将不胜感激。

编辑:我只是看了一下UIWindow的setRootViewController文档,这里是Apple对它的评价:

根视图控制器提供窗口的内容视图。将视图控制器分配给此属性(以编程方式或使用Interface Builder)将视图控制器的视图安装为窗口的内容视图。如果窗口具有现有视图层次结构,则在安装新视图之前将删除旧视图。

ios uiview ios8 uikit
3个回答
2
投票

我注意到了同样的事情。

基本上,我有一个相当复杂的故事板,充当登录/欢迎界面。此界面位于导航控制器中,该控制器以模态方式呈现另一个导航控制器。

在某一点之后,用户采取将他转换到主界面的动作。使用iOS 8视图调试器我注意到在设置窗口的rootViewController属性后,旧的视图层次结构仍然存在。

我的解决方案,现在是在重新配置window.rootViewController属性之前使用以下代码:

for (UIView* subView in self.window.rootViewController.view.subviews) {
    [subView removeFromSuperview];
}
[self.window.rootViewController.view removeFromSuperview];

它不漂亮,但它的工作原理。

我注意到的另一个奇怪的事情是,使用此方法未正确清理欢迎界面的模态呈现的viewController。我必须手动解雇它并清理它。


0
投票
var loginNavigationController: OnBoardViewController?{
    willSet{
        if newValue == nil {
            loginNavigationController?.view.removeFromSuperview()
        }
    }
}

loginNavigationController = nil然后设置window.rootviewcontroller = {Different VC}


0
投票

最好的解决方法是:

self.window.subviews.forEach { $0.removeFromSuperview() }

或者,旧式:

for view in self.window.subviews {
   view.removeFromSuperview()
}
© www.soinside.com 2019 - 2024. All rights reserved.