Могу ли я вставить UINavigationController и установить заголовок над моим экземпляром UITabBarController, созданным пером, в моем приложении-делегате applicationDidFinishLaunching?

Я пытаюсь создать приложение для iPhone с дополнительным навигационным контроллером верхнего уровня.

Его добавление в порядке, но попытка установить заголовок не работает, если вы не пытаетесь добавить свой собственный элемент навигации, после чего приложение вылетает с ошибкой «NSInternalInconsistencyException» по причине: «Невозможно вызвать pushNavigationItem:animated: непосредственно на UINavigationBar управляется контроллером.

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    rootHasNavBar = NO; 

    if (window && viewController)
    {

        // Tab Controller is root:
        if (!rootHasNavBar)
        {
           window.rootViewController = viewController; // viewController:UITabBarController
           [window makeKeyAndVisible];
        }
        else
        {
          // Navigation controller  above UITabBarController
          UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
            window.rootViewController = navigationController;
         //Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot call pushNavigationItem:animated: directly on a UINavigationBar managed by a controller.'

          UINavigationItem* item = [[UINavigationItem alloc] initWithTitle:NSLocalizedString(@"RentalPoint",nil)];
          [ navigationController.navigationBar pushNavigationItem:item animated:YES];

            navigationController.toolbarHidden = YES;
          [window makeKeyAndVisible];

        };


    }

Как мне это сделать? Или есть какая-то техническая причина, по которой я не могу этого сделать?

Обновление: люди, которые предложили просто переместить назначение заголовка контроллера и заголовка элемента навигации в viewDidLoad контроллера, обращались к некоторым внутренним (и крайне неинтуитивным для новичка) аспектам архитектуры Cocoa, которые все еще были мне совершенно незнакомы. Если смотреть со стороны на такой огромный и сложный фреймворк, как Cocoa, который не позволяет вам просматривать исходный код, то это та тайна, которую я нахожу самой сложной. В других моих языках и инструментах я всегда могу прочитать и войти в код, включая мои фреймворки. здесь вы не можете, и поэтому вы должны читать, читать, читать, и, к счастью, есть МНОГО замечательных источников документации.


person Warren P    schedule 08.02.2013    source источник
comment
Не могли бы вы объяснить, как вы объявляете и инициализируете rootHasNavBar? Как насчет viewController, это в nib/раскадровке? Мне странно, что viewController может быть корневым vc окна, тогда он также может быть назначен корневым vc нового навигационного контроллера.   -  person danh    schedule 09.02.2013
comment
ViewController представляет собой экземпляр UITabBarController, созданный пером, и является корневым контроллером, если только мне не нужен UINavigationController над ним. BOOL читается из prefs.   -  person Warren P    schedule 09.02.2013


Ответы (2)


Установите заголовок навигации при инициализации вашего UIViewController.

self.title = @"My Title";
self.navigationItem.title = @"Nav Title"; //note: this will show-up in the back button when you push a subsequent view

или, если вы действительно хотите жестко запрограммировать его в подпрограмме applicationDidFinishLaunching, вы можете просто сделать:

viewController.title = @"My Title";
person Joel    schedule 08.02.2013
comment
Если мой UIViewController создан с помощью nib, я могу настроить их в Interface Builder без какого-либо кода, верно? - person Warren P; 09.02.2013
comment
stackoverflow.com/questions/7418511/ - person Joel; 09.02.2013
comment
Принятие этого ответа, потому что это то, что мне было проще всего сделать. Другой ответ также работает. - person Warren P; 11.02.2013

Я полагаю, что контроллер панели вкладок в качестве корня контроллера навигации является более сложным случаем, поэтому я сделал это в IB, оставив более простой случай для кода. Сначала я сделал следующее (все в IB):

  1. создал новый проект с одним видом
  2. удалил vc по умолчанию и добавил vc навигации
  3. удалил корень навигации по умолчанию vc (таблица vc)
  4. нарисовал контроллер панели вкладок и сделал так, чтобы корень
  5. проверил элемент навигации контроллера панели вкладок и установил его заголовок на «Rental Point».

Я думаю, что это дает моему приложению «необязательный случай», на который вы ссылаетесь, с контроллером панели вкладок, окруженным контроллером навигации (вы сказали «над ним», но ваш код говорит «вокруг него, с ним как корень»).

Теперь более простой случай легче реализовать в appDidFinishLaunching следующим образом...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // if I don't want the optional case, if I just want a tab bar controller as 
    // my window's root, grab it from the navigation controller, and make it the window's
    // root (thereby abandoning the navigation controller)

    if (YES) {
        UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
        self.window.rootViewController = [navVC.viewControllers objectAtIndex:0];
    }

    return YES;
}
person danh    schedule 09.02.2013
comment
Я думаю, что это проблема моего кода? Я хочу, чтобы он был визуально выше, не обязательно с другим видом внутри него. - person Warren P; 09.02.2013
comment
Вы определенно создаете этот навигационный контроллер с контроллером панели вкладок в качестве корня, что немного необычно. В случае, когда вы хотите, чтобы навигационный контроллер находился над пользовательским интерфейсом по умолчанию, что вы хотите иметь в качестве корня навигационного контроллера? - person danh; 09.02.2013
comment
Я знаю, чего хочу визуально и логически (чтобы иметь возможность использовать навигационный контроллер для возврата на этот домашний экран с помощью кнопки «Назад»), но не уверен, что мне следует использовать в качестве корневого контроллера приложения. - person Warren P; 11.02.2013
comment
Итак, можем ли мы думать о вашем приложении как о приложении с вкладками, за исключением некоторых обстоятельств, когда вы хотите представить навигационный контроллер (сверху, без видимых вкладок основного приложения). этот навигационный контроллер должен выполнять обычную детализацию, но иметь кнопку «Назад» на корневом уровне, и эта кнопка «Назад» должна отклонять навигационный контроллер и снова открывать контроллер панели вкладок ??? (это полный рот. если это то, что вы хотите, я думаю, что знаю, как это сделать). - person danh; 11.02.2013