UIWindow setRootViewController不清除现有层次结构

时间:2014-11-07 07:01:53

标签: ios uiview ios8 uikit

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

在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)将视图控制器的视图安装为   窗口的内容视图。如果窗口具有现有视图   层次结构,旧视图在新视图之前被删除   安装。

3 个答案:

答案 0 :(得分:2)

我注意到了同样的事情。

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

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

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

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

它不漂亮,但它有效。

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

答案 1 :(得分:0)

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

loginNavigationController = nil 然后设置window.rootviewcontroller = {不同的VC}

答案 2 :(得分:0)

最好的解决方法是:

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

或者,以旧样式:

for view in self.window.subviews {
   view.removeFromSuperview()
}