Пользовательская навигация iOS с вложенными контроллерами представления - PullRequest
1 голос
/ 25 марта 2011

Я не совсем уверен, что лучше всего это делать, поэтому я подумал, что спросить.

Вот цель программы:

  • Пользовательский контроллер навигации, созданный с помощьюroot UIViewController, который фактически не подкласс UINavigationController (для простоты манипулирования дизайном)
  • Вложенные контроллеры представления для разных экранов (управляются контроллером основного представления)
  • Каждый вложенный контроллер представления имеет собственный файл пера

В настоящее время у меня это работает, однако каждый вложенный контроллер представления - это не контроллер представления, а подкласс UIView.Я чувствую, что это плохая практика, потому что я использую эти UIViews способом контроллера представления, но без функций контроллера представления (то есть. ViewDidLoad).Кроме того, эти UIViews принимают обычные методы делегата UIViewController (который действительно устанавливает красные флаги).

Это на самом деле плохая практика?

Вещи, которые я боюсь при попытке переключитьUIViewControllers - это то, что мне все равно придется создать подкласс UIView, чтобы определить, на какое представление указывать, когда я загружаю перо через:

NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];

for (id object in bundle) {
    if ([object isKindOfClass:[SubclassedUIView class]])
        currentScreenViewController = (SubclassedUIView *)object;
}

Я еще не проверял, но я предполагаю, что долженсделать "SubclassedUIView", а не просто UIView в этом операторе, потому что в комплекте есть другие объекты UIView.Но опять же, эта ситуация может быть лучше, чем текущая.

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

Есть идеи?

Ответы [ 2 ]

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

Создайте подкласс UIViewController для каждого типа SubclassedUIView, отметив опцию, чтобы создать файл XIB для интерфейса, и переместить весь код к нему, указывая его на self.view. Затем откройте Interface Builder с помощью .xib для этого контроллера представления и настройте внешний вид UIView так, как вам нравится. Чтобы манипулировать визуальными элементами из контроллера основного вида, вам нужно будет либо присвоить номера «Tag» каждому элементу, либо создать целую кучу IBOutlet переменных экземпляра и подключить их к вашим элементам в IB. Правильно представить контроллеры с помощью UINavigationController:

/* at the top of your main view controller */
#import "SubclassedUIViewController.h"

/* when navigating to the next view */
SubclassedUIViewController *newController = [[SubclassedUIViewController alloc] initWithNibName:@"SubclassedUIViewController" bundle:nil];
[(UILabel *)[newController.view viewWithTag:6] setText:@"Text"]; // example of accessing elements using tags
[newController.textLabel setText:@"Text 2"]; // example of accessing elements using IBOutlet connections
[self.navigationController pushViewController:newController animated:YES];
[newController release];

Интерфейсный конструктор также позволяет добавлять контроллер навигации в файл .xib контроллера основного вида и предоставлять текст кнопки возврата, основной заголовок и т. Д. При реализации контроллеров представления в подклассе переопределите initWithNibName:bundle: и установите self.navigationItem.title и любые другие свойства self.navigationItem, которые вы хотите.

РЕДАКТИРОВАТЬ : Вы имели в виду, что вы должны иметь возможность манипулировать определенными свойствами некоторых подклассовых представлений, в то время как в других? Как, вам требуется доступ ко всем из них все время? Если это так, то подключите свои подклассовые виды после загрузки контроллера основного вида, то есть:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.subclassedController1 = [[SubclassedUIViewController1 alloc] initWithNibName:@"SubclassedUIViewController1" bundle:nil];
    // self.subclassedController2 = ... etc
}

/* in your loading next view code you can skip the alloc/init line */
[self.navigationController presentViewController:subclassedController2 animated:YES];

И затем в ваших подклассных контроллерах вы можете добраться до главного контроллера несколькими способами:

  1. Звонок на self.parentViewController
  2. Вызов [(MyCustomAppDelegateClass *)[[NSApplication sharedApplication] delegate] rootView] или аналогичный (по сути, ссылка, которую ваш делегат приложения держит на главный вид приложения).
  3. Путем добавления свойства @property (assign) и ivar к подклассовому контроллеру, указывающему на контроллер основного вида. Вы можете назначить это при загрузке контроллера основного вида с помощью subclassedController1.mainViewController = self.

Полезные документы:

  1. Руководство по программированию контроллера представления для iOS: навигационные контроллеры
  2. Краткое руководство по Xcode (обновлено для Xcode 4)
0 голосов
/ 25 марта 2011

Видимо, то, что я делал, было нормально в соответствии с Как добавить представление UIViewController как подпредставление .

...