从AppDelegate获取故事板定义的UINavigationController

10
在故事板中,我有一个引导视图控制器,它会淡入一个UINavigationController。

在Storyboard(故事板)中,我有一个介绍性的视图控制器,它会渐变成一个UINavigationController(导航控制器)。

      |   |      |   |
   -> |   |  ->  |   |     
      |   |      |   |
     ViewCtrl   NavCtrl

我想从应用程序委托中获取导航控制器的引用(就像@Guillaume在这个问题的回答中所做的那样)。

下面是我尝试访问它的方法:

UIApplication.sharedApplication.delegate.window.rootViewController.navigationController;

但导航控制器是空的。

有没有想过为什么navController是空的,或者我该怎么做才能得到对它的引用?


谢谢@rocir!看起来很有前途。我唯一的反对意见是应该已经实例化了一个UINavigationController,并且我想获取对那个的引用。我不认为我想要实例化第二个导航控制器。 - bbrame
但是你现在这样做是行不通的,因为你的rootViewController不在UINavigationController中。此外,在这个时候,UIViewController还没有被实例化。所以你有任何连接这两个视图控制器的segue吗? - rocir
据我所知,您无法从ViewCtrl访问它,因为它不在NavCtrl中。这可能适用于将rootViewController放置在导航控制器内的应用程序。我不确定他的代码是否以这种方式工作。如果您真的想以这种方式做,我建议在AppDelegate中创建一个属性(如navigationController),并在第一次初始化时设置它。之后,您只需访问此属性即可获取它。 - rocir
或者,您可以将导航控制器反转并使其成为rootViewController。然后,您只需推送介绍性视图控制器一次,以后再也不需要推送它(在未来的应用程序启动中,您不再需要推送它)。然后,您就可以访问导航控制器作为根视图控制器。 - rocir
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/36053/discussion-between-rocir-and-bbrame - rocir
显示剩余3条评论
2个回答

25
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                                         bundle: nil];

UINavigationController *controller = (UINavigationController*)[mainStoryboard 
                    instantiateViewControllerWithIdentifier: @"<Controller ID>"];
您可以在导航控制器的属性检查器中指定导航控制器的控制器标识符。

它在“身份检查器”中(从左数第三个)。 - Ali
3
每次调用此函数都会返回一个新的导航控制器实例。 - Mohamed Elkassas
@MohamedElkassas 没错。从storyboard获取任何控制器都会每次“实例化”新对象。从storyboard中没有“共享实例”的概念。如果您想要这样的共享实例,应该在appdelegate上实例化它一次,然后通过appdelegate在应用程序的任何地方访问它。 - Chen Li Yong
这将每次返回导航控制器的新实例。 - ViruMax

2

所以 Arsen 的解决方案看起来不错,但我不知道如何获取我的故事板的名称哈哈。对我而言,可行的方法是:

UINavigationController *navigationController = (UINavigationController*)_window.rootViewController;
AVDashboardViewController *dashBoardViewController =
(AVDashboardViewController*)[navigationController.viewControllers  objectAtIndex:1];//since on index 0 I have my login screen and index 1 is the home screen

在AppDelegate中获取NavigationController的引用可能看起来像是不好的编程实践,但在我的情况下,我需要它,因为那是...
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 

is located,这是在接收到通知时调用的方法之一。我也曾经苦恼于如何在收到消息后更新导航控制器,所以也许有些离题,但这里有一个免费的提示:

UIBarButtonItem *notiButton = [[UIBarButtonItem alloc] initWithTitle: @"Received push!" style: UIBarButtonItemStyleBordered target:self action:nil];

[[dashBoardViewController navigationItem] setLeftBarButtonItem:notiButton animated:YES];

[navigationController popToViewController:dashBoardViewController animated:YES];

希望能对你有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接