Программная навигация в iOS - PullRequest
1 голос
/ 24 марта 2011

Я в процессе портирования существующего приложения Android на iOS, и я довольно неопытен в этой среде. Все примеры, которые я читал для навигации по нескольким представлениям, используют какой-то визуальный пользовательский элемент управления для запуска загрузки и выгрузки видов (панель вкладок, панель навигации). Навигация этого приложения должна быть довольно строгой и не позволять пользователю свободно перемещаться между тремя видами.

Приложение должно иметь полноэкранное представление-заставку, основное представление, с которым взаимодействует пользователь, и третье представление для сбора данных. Должен появиться экран-заставка, и пользователь должен перейти к основному виду при нажатии на изображение-заставку. В главном контроллере представления будет настраиваемая логика для определения, требуются ли данные, в какой момент они должны перейти к представлению сбора данных. После того, как введены правильные данные и пользователь нажимает кнопку ОК, он должен вернуться к основному виду.

До сих пор я читал, что все представления должны иметь связанный класс UIViewController, и самый простой способ сделать это - создать класс XIB и UIViewController одним выстрелом и связать их вместе (у меня много примеров / книг / учебники, которые я могу ссылаться на эту часть). Я считаю, что я прочитал, что приложение должно иметь корневой UIViewController, который обрабатывает загрузку других и перемещение между ними.

Мои вопросы: Из какого класса я должен извлекать контроллер основного представления, который я использую для загрузки других? Как я могу подключить это к приложению, чтобы оно знало, чтобы загрузить его в качестве основного контроллера? Каков общепринятый стандартный способ иметь контроллер навигации в приложении и позволить другим представлениям получить ссылку на него? Должны ли мои UIViewControllers содержать ссылку на их родительский контроллер, или они должны запросить UIApplication ссылку на него при необходимости? Как мне убедиться, что я не создаю экземпляров дополнительных копий представлений и их контроллеров во время навигации пользователя?

Ответы [ 5 ]

7 голосов
/ 24 марта 2011

Из какого класса мне следует извлекать контроллер основного представления, который я использую для загрузки других?

UIViewController

Как подключить этот провод?в приложение, чтобы оно могло загрузить его в качестве основного контроллера?

Прочитать раздел «Определение своего подкласса» Руководство по программированию контроллера представления для iOS .Поцарапайте это - прочитайте все это.Это все важно, вы могли бы начать изучать это сейчас.Также прочитайте Руководство по программированию приложения для iOS .Опять же, прочитайте все это, но часть жизненного цикла приложения является наиболее релевантной для вашего вопроса.

Каков общепринятый стандартный способ использования контроллера навигации в приложении иразрешить другим видам получить ссылку на него?

Опять же, это хорошо объяснено в Руководство по программированию контроллера вида .Представления никогда не должны заботиться о контроллере навигации, но любые контроллеры представления, являющиеся частью стека навигации, имеют прямой доступ к контроллеру навигации через свои соответствующие свойства navigationController.

Если мои UIViewControllers содержат ссылкук их родительскому контроллеру, или они должны запросить UIApplication для ссылки на него, когда это необходимо?

Контроллер представления уже имеет ссылку на свой родительский контроллер в своем (удивление!) parentController свойстве.Для контроллера лучше избегать слишком многого о своем родителе.Если контроллер ожидает, что его родитель является определенным типом или отвечает на определенные сообщения, становится труднее повторно использовать этот контроллер или реорганизовать ваше приложение.Попытайтесь дать контроллеру то, что он должен делать, когда вы его создаете.Если контроллеру потребуется запросить дополнительные данные или что-то в этом роде, делегирование - это хороший способ.

Как мне убедиться, что я не создаю дополнительных копий представлений и их контроллеровкак пользователь перемещается?

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

7 голосов
/ 24 марта 2011

Похоже, что вы можете выполнить то, что вам нужно, с помощью нескольких основных вызовов.Чтобы программно вызвать контроллер представления:

- (void)showController {
    MyViewController *myController = [[MyViewController alloc] initWithNibName:@"MyViewControllerXIB" bundle:nil];

    [self.navigationController pushViewController:myController animated:YES];
    [myController release];
}

Чтобы вернуться к предыдущему представлению, просто вызовите из любого контроллера представления:

- (void)goBack {
    [self.navigationController popViewControllerAnimated:YES];
}

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

3 голосов
/ 24 марта 2011

Не совсем верно - каждый UIViewController должен знать, как вызывать своих потомков.Для Apple предпочтительный путь навигации по представлениям - это ветвящееся дерево с предупреждением о вкладках, которые объединяют несколько контроллеров представления в один узел дерева.

Вы явно не обрабатываете загрузку.Обычно у вас есть достаточные отношения между вашими NIB, чтобы классы контейнера загружались автоматически.Какао будет тогда загружать представления всякий раз, когда они необходимы, но еще не загружены (что является целью loadView и viewDidLoad), и сохранять их до тех пор, пока предупреждение о нехватке памяти не потребует их очистки (что приводит к viewDidUnload).Относительно редко вы сами явно загружаете NIB (хотя ячейки табличного представления являются очевидным примером, когда программная загрузка NIB довольно распространена).

Таким образом, вы, вероятно, получите:

  • заставка или предварительный просмотр первого контроллера представления, как Default.png
  • контроллер представления, который, вероятно, отображает Default.png и имеет два выхода, идущих к контроллеру сбора данных и главному контроллеру
  • когда пользователь нажимает кнопку на главном экране, спросите модель, нужен ли сбор данных.Если это так, то перейдите к контроллеру сбора данных, в противном случае перейдите к главному контроллеру
  • , дайте контроллеру сбора данных выход на главный контроллер и дайте ему выполнить навигацию там в соответствующий момент

Вы получаете MainWindow.xib бесплатно при создании проекта на основе нового представления.Вероятно, самое простое - поместить ссылки на три подкласса UIViewController, но настроить каждый из них для загрузки из других файлов.Установите связи между ними в MainWindow.xib, установите ссылки на вещи в соответствующих представлениях в соответствующих XIB.

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

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

[self.parentViewController dismissModalViewControllerAnimated:YES];

Поскольку модель в идеале является отдельной независимой вещью, все контроллеры действительно должны знать, какие другие контроллерыони могут представить, как заполнить себя из модели и как перенести данные обратно в модель.Вы редко сталкиваетесь с особенно сложными связями между контроллерами представления.

0 голосов
/ 19 ноября 2013

Вы можете указать, какой ViewController загружать первым. Если приложение основано на навигации, используйте следующий код:

AppDelegate.m

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
    MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
    self.nav = [[UINavigationController alloc] initWithRootViewController:mainViewController];
    [_window addSubview:nav.view];
    [_window makeKeyAndVisible];
  }

Если приложениена основе просмотра используйте следующий код:

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
  }
0 голосов
/ 24 марта 2011

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

Вот официальное введение от Apple:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...