NSViewController не создается

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

В построителе интерфейса я могу перетащить NSViewController в xib, назначить ему собственный класс контроллера и назначить его представление соответствующему представлению в xib. Вот проблема: ни initWithNibName:Bundle:, ни loadView не вызываются.

Что мне не хватает?

РЕДАКТИРОВАТЬ: Люди, кажется, неправильно понимают вопрос, поэтому я уточню.

В окне уже есть контроллер представления. Я хочу назначить отдельные контроллеры представлений нескольким подпредставлениям. Мне нужно знать, как связать мой NSViewController подкласс с соответствующим NSView подклассом (который является дочерним по отношению к главному окну).

Другими словами, я пытаюсь использовать несколько подклассов NSViewController для управления множеством различных настраиваемых представлений (по одному на каждое) в одном файле .xib. Эти контроллеры и подпредставления имеют свои собственные .xib-файлы, которые в конечном итоге должны стать видимыми в том же окне.


person mtmurdock    schedule 04.02.2012    source источник
comment
Откуда вы имеете в виду NSViewController?   -  person Patrick Perini    schedule 05.02.2012
comment
Я добавляю его в файл xib (перетаскивая), а затем назначаю его класс классу, который я создал с помощью IB. С правой стороны есть вкладка, позволяющая указать владельца файла.   -  person mtmurdock    schedule 05.02.2012
comment
Верно, но если вы просто поместите объект в любом месте xib, он не обязательно будет отображаться, особенно объект, не относящийся к View, например NSViewController. Вы должны либо создать экземпляр NSViewController из кода (в этом случае ваш xib будет поддерживать ссылку на него как File's Owner), либо установить его как rootViewController из ApplicationDelegate window.   -  person Patrick Perini    schedule 05.02.2012
comment
Я делаю это в своем приложении, используя метод, описанный в моем ответе. Один верхний контроллер и несколько дочерних контроллеров. Я отредактировал свой ответ образцом из своего приложения.   -  person Roger    schedule 07.02.2012


Ответы (2)


Шаблон, который я использую для NSViewController, должен иметь xib для каждого контроллера представления. Затем, когда вам понадобится этот контроллер представления, вы alloc его и используете метод initWithNibName:Bundle:. Как только вы воспользуетесь его представлением, будет вызван loadView.

Пример:

self.editViewController = [[[MyEditViewController alloc] initWithNibName:@"MyEditViewController" bundle: nil] autorelease];
[self.window setContentView: editViewController.view];
person Jorge    schedule 05.02.2012
comment
Это не моя проблема, я пытаюсь создать контроллер представления для подпредставления. - person mtmurdock; 07.02.2012
comment
@mtmurdock Вы проверили, что компонент контроллера, который вы перетащили в xib, действительно содержит экземпляр вашего контроллера? - person Roger; 07.02.2012

Раньше я тоже зацикливался на этом и отказался от этой штуки - синего круга с белой рамкой в ​​нем из палитры IB. Теперь я создаю свои контроллеры из кода и устанавливаю ссылку в IB только на класс-владелец файла через владельца файла: щелкните правой кнопкой мыши владельца файла, введите имя класса в инспекторе идентичности и затем установите соединение из представления владельца файла с Посмотреть.

Затем в соответствующей точке инициализации в коде вы выполняете:

[self setMyViewController = [[MyViewController alloc] initWithNibName: @"MyView" bundle: [NSBundle mainBundle]]

В вашем конкретном случае это может быть windowDidLoad метод, когда ваше окно загружается из пера и готово к работе. Затем вы можете добавить представление в представление содержимого Windows. Также вы можете подумать о соотношении 1: 1 между представлением и контроллером представления. Это значительно упрощает обслуживание.

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

@property (...) MyViewController *myViewController;

Добавьте строку кода, чтобы фактически создать контроллер (см. Выше). Затем с помощью инспектора привязок привяжите компонент палитры к свойству myViewController.

Итак, вам не хватает того, что вы фактически не создаете экземпляр объекта контроллера.

РЕДАКТИРОВАТЬ 2: Вот код (awakeFromNib - это метод верхнего контроллера). Он создает два дочерних контроллера, каждый из которых обрабатывает разные подпредставления:

- (void) awakeFromNib {

    [[self startEndTopicHeader] setHeader: @"Event timeline boundary"];
    [[self startDateHeaderView] setHeader: @"Event (start) date"];
    [[self endDateHeaderView] setHeader: @"Event end date"];

    [self setStartDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
    [[[self startDateViewController] view] setFrame: [[self dummyStartView] bounds]];
    [[self dummyStartView] addSubview: [[self startDateViewController] view]];
    [[self startDateViewController] setParentController: self];

    [self setEndDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
    [[[self endDateViewController] view] setFrame: [[self dummyEndView] bounds]];
    [[self dummyEndView] addSubview: [[self endDateViewController] view]];
    [[self endDateViewController] setParentController: self];

}
person Roger    schedule 05.02.2012