从AppDelegate以Storyboard方式编程实例化视图控制器

12

我正在忙于开发一个应用程序 - 当它首次启动时,会要求用户完成两个步骤:

  1. 选择一个国家
  2. 接受条款和条件

从那里进入主视图控制器。

我目前面临的问题是如何从我的应用程序代理将第一个视图控制器推送到屏幕上。我正在使用故事板/ Xcode 5 / iOS7。

以下是我编写的代码:

UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle: nil];
BBCounterySettingsViewController *controller = (BBCounterySettingsViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"CountrySettings"];
[navigationController pushViewController:controller animated:NO];
问题是当应用程序到达代码的最后一行时会崩溃,并显示以下错误信息:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController pushViewController:animated:]: unrecognized selector sent to instance 0x8e9a400'

有没有人知道我哪里做错了?
4个回答

11

你期望self.window.rootViewController是一个UINavigationController,但实际上它是一个UIViewController。这意味着你在Storyboard中最外层的视图控制器类型是错误的。

获取 UINavigationController(在此情况下应该有效)的更好方法是在任何 UIViewController 中使用属性 self.navigationController

根据我的理解,您想在用户首次运行时呈现视图,以让用户选择一些内容。那么你应该使用模态视图控制器来呈现,像这样:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//isFirstRun is some boolean you use to determine if it's the first run
if(isFirstRun){
    BBCounterySettingsViewController *controller = (BBCounterySettingsViewController *)[mainStoryboard instantiateViewControllerWithIdentifier: @"CountrySettings"];
    [self.window.rootViewController presentViewController: controller animated:YES completion:nil];
}

我觉得我可能走错了这个方法。这个视图控制器不需要导航到其他任何地方,只需要被关闭。应用程序的其余部分是基于选项卡栏的。在应用程序委托中,self.navigationController不存在? - Robert J. Clegg

7

你需要做两件事:

  1. In Storyboard you have mentioned the controller name (eg LoginView) and enable use storyboard ID
  2. Then you have user the below line

    loginView = [storyboard instantiateViewControllerWithIdentifier:@"LoginView"];
    [(UINavigationController*)self.window.rootViewController pushViewController:loginView animated:NO];
    
希望这能帮到您。如果问题仍然存在,请告诉我。

谢谢,这也有所帮助。 - Robert J. Clegg
如果将您的viewController嵌入到某个UINavigationController中,您还可以使用UIStoryBoard中的instantiateInitialViewController()方法。这会自动加载在您的storyboard上标有箭头的viewController。如果此viewController是一个容器,则其子项也会被加载。 - Vinzzz

0
[self performSegueWithIdentifier:@"buyListSegue" sender:sender];

不太有用。从AppDelegate或者不是UINavigationController的viewControllers中无法进行Segue转场。 - Robert J. Clegg

0

我认为控制器标识符"CountrySettings"设置错误了。你没有得到一个NavigationController,所以无法调用pushViewController...


问题已解决,谢谢。标记的答案是问题所在。 - Robert J. Clegg

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