2009-11-24 72 views
118

所以,我推視圖控制器從RootViewController的一樣:如何從推控制器獲取RootViewController?

 
[self.navigationController pushViewController:anotherViewController animated:YES] ; 

,但從現在anotherViewController,我想再次訪問RootViewController的。

我想

 
// (inside anotherViewController now) 
///RootViewController *root = (RootViewController*)self.parentViewController ; // No. 
// err 
RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works 

我不知道爲什麼這工作,我不知道,如果它的最好辦法做到這一點。有人可以評論一個更好的方式來從你推入RootViewController的navigationController的控制器獲取RootViewController,以及我做的方式是否可靠?

+0

如果你想訪問「後退」視圖控制器,你所做的將可靠地獲得根視圖控制器(導航層次中的第一個控制器) r,看我的答案。 –

+0

[另請參閱「設置UIWindow的rootViewController做什麼?」](http://stackoverflow.com/questions/8204059/what-does-setting-the-uiwindows-rootviewcontroller-do) – bobobobo

回答

128

使用UINavigationController的viewControllers屬性。示例代碼:

這是獲取「後退」視圖控制器的標準方式。原因objectAtIndex:0的作品是因爲您試圖訪問的視圖控制器也是根視圖控制器,如果您在導航方面更深入,後視圖將不會與根視圖相同。

+5

:) ty。它仍然似乎哈克 - :)我真的想要一個「官方」成員來做這項工作,像self.navigationController.rootViewController,但唉,沒有這樣的事情.. – bobobobo

+58

上面的代碼是錯誤的。 'rootViewController'在它之前缺少'*',並且索引應該只是'0'。問題中的代碼是正確的:'RootViewController * root =(RootViewController *)[navigationController.viewControllers objectAtIndex:0]' – ma11hew28

+1

同意:上面的代碼返回* parent *視圖控制器,而不是* root視圖控制器作爲OP問。不過,這就是本S說他會做的,他只是沒有足夠的指出。 –

138

斯威夫特版本:

var rootViewController = self.navigationController?.viewControllers.first 

的ObjectiveC版本:

UIViewController *rootViewController = [self.navigationController.viewControllers firstObject]; 

如果自我是嵌入在一個UINavigationController一個UIViewController的實例。

+0

我可以從另一個類獲得另一個ViewController的navigationController嗎? – sasquatch

+0

任何UIViewController子類都有一個navigationController屬性,它指向它的第一個parentViewController,它與UINavigationController類相匹配。 – dulgan

+0

做了訣竅和最簡單的答案:)謝謝 – MBH

12

一個稍微不那麼難看版本所有這些問題的答案:

UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject]; 
你的情況

,我可能會做這樣的事情:

您的UINavigationController子類內:

- (UIViewController *)rootViewController 
{ 
    return [[self viewControllers] firstObject]; 
} 

那麼你可以使用:

UIViewController *rootViewController = [self.navigationController rootViewController]; 

編輯

OP要求在評論的屬性。

,如果你喜歡,你可以通過類似self.navigationController.rootViewController只需添加一個只讀屬性,以你的頭訪問此:

@property (nonatomic, readonly, weak) UIViewController *rootViewController; 
3

作爲除了@dulgan's答案,它始終是在使用firstObject一個好方法objectAtIndex:0,因爲如果數組中沒有對象,則第一個返回nil,後一個拋出異常。

UIViewController *rootViewController = self.navigationController.viewControllers.firstObject; 

或者,它會是一大利好,爲您創建一個名爲UINavigationController+Additions類別和定義你的方法。

@interface UINavigationController (Additions) 

- (UIViewController *)rootViewController; 

@end 

@implementation UINavigationController (Additions) 

- (UIViewController *)rootViewController 
{ 
    return self.viewControllers.firstObject; 
} 

@end 
+0

我剛剛在沒有閱讀你的答案的情況下添加了這部分,你完全正確地使用「firstObject」更好的[0] – dulgan

6

對於所有誰感興趣的迅速擴展,這是我現在使用什麼:

extension UINavigationController { 
    var rootViewController : UIViewController? { 
     return self.viewControllers.first as? UIViewController 
    } 
} 
1

在這裏,我想出了通用方法從任何地方到根導航。

  1. 你創建這個類一個新的類文件,以便它可以訪問在你的項目中的任何地方:

    { 
        ... 
        SharedControllers.navigateToRoot(self) 
        ... 
    } 
    
:從您的項目中的任何地方

import UIKit 

class SharedControllers 
{ 
    static func navigateToRoot(viewController: UIViewController) 
    { 
     var nc = viewController.navigationController 

     // If this is a normal view with NavigationController, then we just pop to root. 
     if nc != nil 
     { 
      nc?.popToRootViewControllerAnimated(true) 
      return 
     } 

     // Most likely we are in Modal view, so we will need to search for a view with NavigationController. 
     let vc = viewController.presentingViewController 

     if nc == nil 
     { 
      nc = viewController.presentingViewController?.navigationController 
     } 

     if nc == nil 
     { 
      nc = viewController.parentViewController?.navigationController 
     } 

     if vc is UINavigationController && nc == nil 
     { 
      nc = vc as? UINavigationController 
     } 

     if nc != nil 
     { 
      viewController.dismissViewControllerAnimated(false, completion: 
       { 
        nc?.popToRootViewControllerAnimated(true) 
      }) 
     } 
    } 
} 
  • 用法

  • 相關問題