簡體   English   中英

更改 UIWindow 的 rootViewController

[英]Changing the rootViewController of a UIWindow

當我的應用程序首次加載時,我將UIWindowrootViewController屬性設置為controllerA

在我的應用程序中的某個時候,我選擇將rootViewController更改為controllerB

問題是,有時當我在controllerB進行翻轉轉換時,我會看到controllerA背后的視圖。 由於某種原因,該視圖沒有被刪除。 更令人擔憂的是,在將rootViewController設置為controllerBcontrollerAdealloc方法永遠不會被觸發。

我嘗試在切換到controllerB之前手動刪除UIWindow的子視圖,這解決了在后台看到controllerA的視圖但controllerA的 dealloc 仍然永遠不會被調用的問題。 這是怎么回事????

蘋果文檔說:

根視圖控制器提供窗口的內容視圖。 將視圖控制器分配給此屬性(以編程方式或使用 Interface Builder)會將視圖控制器的視圖安裝為窗口的內容視圖。 如果窗口具有現有視圖層次結構,則在安裝新視圖之前刪除舊視圖。

更新

這是我的 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()
        }
    }
}

loginNavigationController = nil

這是蘋果的 bug,我們假設 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或任何顏色。 默認值為 nil,這會導致背景透明。 這就是為什么可以看到舊窗口(在其上可見新窗口)的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM