Changing the rootViewController of a UIWindow



当我的应用程序第一次加载时,我将UIWindowrootViewController属性设置为controllerA

在我的应用程序中,我选择将rootViewController更改为controllerB

问题是,有时当我在controllerB中进行翻转转换时,我会看到controllerA的视图在它后面。出于某种原因,该视图没有被删除。更令人担忧的是,在将rootViewController设置为controllerB之后,controllerAdealloc方法永远不会被激发。

在切换到controllerB之前,我尝试手动删除UIWindow的子视图,这解决了在后台看到controllerA的视图的问题,但controllerA的dealloc仍然从未被调用这里发生了什么事

苹果文档称:

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

更新

这是我的AppDelegate的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self showControllerA];
    [self.window makeKeyAndVisible];
    return YES;
}
- (void)showControllerA
{
    ControllerA* a = [ControllerA new];
    self.window.rootViewController = a;
}
- (void) showControllerB {
    ControllerB* b = [ControllerB new];
    self.window.rootViewController = b;
}

事实证明存在两个独立的问题。1) 我在控制器a中有一个保留周期,所以它永远不会被解除锁定。其次,为了更改根视图控制器,您必须首先删除windows子视图(即使文档另有建议)

问题可能出现在ControllerA或ControllerB的实现中,它们可能在代码中保留"self",因此ARC无法自动解除对ViewController的锁定。你能发布ControllerA和ControllerB的实现吗。

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

loginAviationController=nil

这是苹果的错误,我们假设ViewControllerA是当前的rootViewController:

// ViewControllerA.m
- (void)buttonClick {
    [self dismissViewControllerAnimated:YES completion:^{
        // [((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // OK
    }];
    [((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // ViewControllerA's view will not dealloc 
}
// AppDelegate.m
- (void)resetRoot {
    ViewControllerB *controller = [[ViewControllerB alloc] init];
    self.window.rootViewController = controller;
}

如果将窗口的rootViewController重置为此代码,则ViewControllerA的视图将永远不会解除锁定。

一个更简单的解决方案是将新窗口的backgroundColor设置为.white或任何颜色。默认值为零,这将产生透明的背景。这就是为什么旧的窗口(在其顶部可以看到新的窗口)被透过。

最新更新