Как мне управлять заменой UINavigationController на другой UIViewController и обратно?

Вот что у меня есть:

  • Файл MainWindow.xib, настроенный с одним UIViewController (подклассом RootViewController). Этот наконечник загружается при запуске приложения.

  • RootViewController имеет два ivar, настраиваемый подкласс UIViewController и UINavigationController. Оба они загружаются из перьев.

Когда приложение запускается, оба ivar инициализируются из соответствующих перьев, а затем UIViewController.view добавляется как подпредставление RootViewController.view.

Внутри представления UIViewController у меня есть элемент управления, который запускает анимированную замену UIViewController и UINavigationController. Вот где возникает проблема. Своп анимируется, но представления UINavigationController не отображаются должным образом. Я получаю панель навигации без заголовка и ничего больше.

Наконечник UINavigationController и базовая функциональность были протестированы в отдельном проекте, но не было RootViewController.

Итак, у меня вопрос, могу ли я это сделать? Я успешно поменял местами другие подобные контроллеры представления, но никогда не использовал UINavigationController. Я видел некоторую документацию, которая наводит меня на мысль, что это может быть глупая затея, но я еще не убедился в этом.

Решение (вроде):

Я нашел решение (обходной путь? Взломать?), Но это вызывает еще несколько вопросов. Я отказался от использования пера для UINavigationController. Вместо этого я загрузил свой UINavigationController rootViewController из пера, а затем программно создал UINavigationController с помощью initWithRootViewController :.

  NavRootViewController *navRoot = [[NavRootViewController alloc] initWithNibName:@"NavRootViewController" bundle:nil];
  navigationController = [[UINavigationController alloc] initWithRootViewController:navRoot];
  [navRoot release];

Это работает, как я и ожидал. Это приводит меня к выводу, что свойство rootViewController UINavigationController не было установлено должным образом, когда я загружал navigationController из Nib. И вопрос, почему? Должен ли он?


person Rob Jones    schedule 11.02.2010    source источник
comment
Поведение, которое вы описываете (пустое представление с панелью навигации без заголовка) звучит так, как будто ваш контроллер навигации не имеет корневого контроллера. Но без изучения всего вашего проекта это всего лишь выстрел в темноте. Можете ли вы загрузить тестовый проект barebone-комплекта где-нибудь, чтобы показать вашу проблему?   -  person Ole Begemann    schedule 11.02.2010
comment
RootViewController NavigationController должен быть загружен из Nib. Это работало, когда у меня был NavigationController в качестве верхнего ViewController. Я посмотрю, смогу ли я что-нибудь собрать и опубликовать.   -  person Rob Jones    schedule 11.02.2010
comment
Да, вы должны иметь возможность загрузить контроллер навигации с его корневым контроллером, установленным из файла NIB. Попробуйте создать пустой проект на основе навигации в Xcode и скопируйте настройку его MainWindow.xib точно в свой NavController.xib. Корневой контроллер навигационного контроллера должен быть создан в этом файле NIB (как дочерний элемент навигационного контроллера), а его свойство файла NIB должно содержать имя его файла NIB.   -  person Ole Begemann    schedule 11.02.2010
comment
Да, я получил его для работы с пустым проектом на основе навигации. Вот как я начал. Затем я перешел в описанный выше режим, и тут что-то пошло не так.   -  person Rob Jones    schedule 11.02.2010


Ответы (3)


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

В подклассе переопределите все различные init :, initWithNibName: bundle :, viewDidLoad :, viewWillAppear :, viewDidAppear: и любые другие подходящие методы, и в этих переопределениях просто NSLog ("") что-то о том, какой это метод (с параметром значения возможно) и вызовите супер-реализацию.

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

Это даст вам достаточно информации, чтобы найти недостающие вызовы методов, а затем вы сможете решить правильную проблему здесь, либо заполнив радар, или ...

person greggwon    schedule 15.12.2011

В некоторых случаях может потребоваться вызов viewDidLoad и viewDidAppear или awakeFromNib каждый раз, когда вы добавляете UINavigationController обратно в стек UIViewControllers. Кажется, что когда типичный код выполняется из вашего AppDelegate, это Окно или что-то за кулисами делает что-то особенное для UINavigationController, чего presentModalViewController не делает.

person greggwon    schedule 15.12.2011

Думаю, вы упустили концептуальный момент.

UINavigationController контролирует контроллеры представлений вместо представлений. Он контролирует, когда и где загружаются сами контроллеры представления. Сами представления загружаются только как побочный эффект нажатия и выталкивания соответствующих контроллеров.

Поэтому размещение контроллера навигации внутри контроллера представления редко имеет смысл.

Если я понимаю, что вы пытаетесь сделать правильно, у вас должен быть RootController, фактически установленный как свойство rootController UINavigationController (да, номенклатура чрезвычайно сбивает с толку). Затем, когда происходит событие подкачки, вы должны заставить контроллер навигации нажать следующий Посмотреть. Представление RootController исчезнет и будет заменено другим. затем вы можете повторить процесс для произвольного количества контроллеров представления.

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

person TechZen    schedule 11.02.2010
comment
Спасибо за ответ. Моим планом Б было сделать UINavigationController главным контроллером представления. Я действительно хотел понять, почему это не работает. Сейчас он у меня работает, и я опубликую дополнительную информацию в своем вопросе, потому что я все еще не понимаю некоторых вещей. Я думаю, что план Б на самом деле станет планом А, как только я буду уверен, что справлюсь с некоторыми вещами. - person Rob Jones; 11.02.2010
comment
Вы определенно хотите, чтобы ваш дизайн работал с API, а не боролся с ним. Я знаю, от этого заболит сердце. - person TechZen; 12.02.2010
comment
Но вы упустили суть. Иногда вам не нужно, чтобы UINavigationController был вашим корнем. В проекте, над которым я сейчас работаю, мне действительно нужны два UIViewController, между которыми я могу переключаться, и чтобы каждый загружал свой собственный контроллер навигации. Вы предлагаете не делать этого, а не реальное решение. - person Ben Lachman; 12.02.2010
comment
Ну и да, и нет. Практически во всех случаях вам нужен иерархический контроллер, управляющий всеми контроллерами представления в приложении. Например, у вас есть панель вкладок с отдельным контроллером навигации на каждой панели. Эти навигационные контроллеры находятся внизу иерархии панели вкладок. То же самое для простого обмена взглядами. В идеале должен быть контроллер навигации или аналогичный контроллер (настраиваемый или нет), который управляет отображаемой парой контроллер представления / представление и тем, как переходить к другим представлениям. - person TechZen; 12.02.2010