2013-12-12 5 views
10

Я занят создании приложения - что при запуске в первый раз, он запрашивает у пользователя, чтобы сделать две вещи:инстанцировании View Controller программно с помощью раскадровки из AppDelegate

  1. Выберите страну
  2. Accept T & Cs

Оттуда он переходит к контроллеру домашнего кинотеатра.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, чтобы перенести первый контроллер представления на экран из моего делегата приложения. Я использую раскадровки/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'

У кого-нибудь есть идеи, что я делаю неправильно?

ответ

11

Вы ожидаете, что self.window.rootViewController будет UINavigationController, но это UIViewController. Это означает, что внешний контроллер представлений в вашем раскадровке неправильного типа.

Лучшим способом получения UINavigationController (который должен работать в этом случае) является использование имущества self.navigationController на любом UIViewController.

Из того, что я понимаю, вы хотите представить представление при первом запуске пользователя, чтобы пользователь мог выбрать какой-то материал. То, что вы должны делать то, присутствует контроллер представления модально, как это:

- (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]; 
} 
+0

Я думаю, что я использую этот подход неправильно. Этот диспетчер представлений не должен перемещаться нигде. Просто нужно уволить. Остальная часть приложения - это приложение на основе панели вкладок. В приложении делегат self.navigationController не существует? – Tander

+0

Я обновлю свой ответ новым советом, то :) – Rick

7

Есть две вещей, которые нужно сделать:

  1. В раскадровке вы упоминали имя контроллера (например, LoginView) и позволяет использовать раскадровку ID
  2. Тогда у вас есть имя и ниже линии

    loginView = [storyboard instantiateViewControllerWithIdentifier:@"LoginView"]; 
    [(UINavigationController*)self.window.rootViewController pushViewController:loginView animated:NO]; 
    

Надеюсь, это поможет. Дайте мне знать, если у вас все еще проблема.

+0

Спасибо, это тоже помогло. – Tander

+0

Если вы встраиваете свой viewController в некоторый UINavigationController, вы также можете использовать 'instantiateInitialViewController()' метод thom 'UIStoryBoard'. Это автоматически загружает viewController, отмеченный стрелкой на вашем раскадровке. Если этот viewController является контейнером, его дети тоже будут загружаться. – Vinzzz

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

Этот ответ может помочь с некоторыми объяснениями ... –

+0

Не полезно. Segues не может произойти из AppDelegate или viewControllers не является частью UINavigationController – Tander

0

Я думаю, что идентификатор контроллера "CountrySettings" установлен в неправильном контроллере. Вы не получаете NavigationController, где можете позвонить pushViewController ...

+0

Решил проблему, спасибо. Отмеченный ответ был вопросом. – Tander

Смежные вопросы