簡體   English   中英

將視圖控制器推入導航控制器后,不會觸發viewDidLoad(和loadView)

[英]viewDidLoad (and loadView) is not fired after the view controller is pushed into navigation controller

將viewController推入導航控制器后,不會立即加載viewController的視圖。

這是我的代碼段。

- (void)myMethodInClassA {
    // window's root view controller is navigation controller
    UINavigationController *naviCtrl = (UINavigationController*)[UIApplication sharedApplication].keyWindow.rootViewController;
    MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
    [naviCtrl pushViewController:myVC animated:NO];

    // at this point, myVC's view is NOT loaded
}

當我調用myMethodInClassA ,該方法返回后,將調用myVC的viewDidLoad 我希望在調用導航控制器的pushViewController:animated:且在myMethodInClassA返回之前加載myVC的視圖。

何時精確加載視圖控制器的視圖? Apple的文檔只是說它在首次訪問時已加載。 這有點模棱兩可。 導航控制器的pushViewController:為什么不訪問視圖控制器的視圖?

ps對於最初的模棱兩可的問題感到抱歉。

將視圖控制器(VC)推到導航控制器的堆棧上會使VC成為導航控制器的子視圖控制器(它是容器視圖控制器)。 創建這種子對父關系是一個獨特的步驟,不會導致子VC視圖立即被加載。 而是容器VC在以后加載視圖。 我相信對於“以后”的含義沒有明確的說明-通常是容器VC決定將子VC的視圖集成到容器VC的視圖層次結構中的時候了。 但基本上,它只是在容器VC實施的自由裁量權下發生。

話雖如此, 任何人都可以通過簡單地訪問VC的view屬性來強制加載VC的view 例如,您可以在代碼中添加以下行

myVC.view;

這將觸發loadView然后在MyViewController觸發viewDidLoad

但是,在您的情況下,如果MyViewController需要對已與容器VC關聯的事件做出反應,則最好重寫MyViewController中的以下方法之一(或兩者?):

- (void) willMoveToParentViewController:(UIViewController*)parent
{
    // write your code here
}

- (void) didMoveToParentViewController:(UIViewController*)parent
{
    // write your code here
}

但是,您需要知道,當從其父導航控制器的堆棧中彈出MyViewController時,也會調用willMoveToParentViewControllerdidMoveToParentViewController 您可以通過檢查parent參數nil來檢測到這種情況。

(快速2)由於此問題沒有可接受的答案...

我最終要做的是在子視圖控制器上創建一個便捷初始化:

convenience init() {
    self.init(nibName: "ChildViewController", bundle: nil)
    //initializing the view Controller form specified NIB file
}

並在parentViewController的viewDidLoad()中

let commentsView = CommentsViewController()
self.addChildViewController(commentsView)
self.momentsScrollView.addSubview(commentsView.view)
commentsView.didMoveToParentViewController(self)

如上所述,當推入視圖時,viewDidLoad會被調用一次,您可能需要在viewWillAppear或viewDidAppear中進行處理。

是的,如果該ViewController已被推入navigationController堆棧中,則不會再次調用ViewDidLoad方法。 第一次按下該ViewController時,將調用viewDidLoad。 因此,如果您需要每次都執行某些功能,請在viewWillAppear方法中實現它,因為每次您按下viewController時都會調用它。

希望對您有幫助。

您是否為第一個tym推送了視圖控制器?如果是,則僅會調用該控制器的viewDidLoad(),如果已被推送且不是第一個tyn,則將調用viewWillAppear()。每推一個鼠標,創建一個新實例,就會調用viewDidLoad()。

暫無
暫無

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

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