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

В моем приложении Какао у меня есть два файла NIB/XIB, которые мне нужно подключить:

  1. MainMenu.xib: содержит пользовательский объект для объекта делегата NSApplication и подключает его к соответствующему выходу в NSApplication заполнитель.

  2. ContextMenu.xib: устанавливает NSMenu; одна запись должна открывать диалог настроек

Мой пользовательский делегат приложения определяет IBAction вызвать окно настроек для моего приложения.

Как я могу подключить NSMenuItem (второй NIB) для отображения предпочтений к действию, определенному в делегате приложения (первый NIB)?

Документы говорят, что это должно быть легко, но они не упоминают, как именно это сделать в Интерфейсном Разработчике:

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

Мне как-то нужно получить доступ к делегату приложения во втором NIB, сообщить Интерфейсному Разработчику, что это мой пользовательский класс (так что он знает о пользовательском IBAction), и подключить его к действию пункта меню.

Спасибо за любые указатели!

4 ответа

Решение

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

Обратите внимание на "если", хотя.

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

Для привязок во втором NIB привязки делегатов приложения можно получить, связавшись с Application с модельным ключевым путем, начинающимся с delegate, т.е. delegate.managedObjectContext

Предупреждение: не создавайте объект делегата приложения во втором NIB. Если вы это сделаете, у вас будет второй экземпляр делегата приложения со вторым, отдельным управляемого ObjectContext. NIB создает другой объект делегата приложения. Это ужасно.

В загрузке MainMenu.xib, [NSApplication sharedApplication] получает свой делегат, установленный для объекта делегата, созданного в MainMenu.xib. Если вы создаете объект делегата в другом NIB, у вас будет объект делегата, который не соответствует [NSApp delegate], (И вы врежетесь головой в стену, пытаясь выяснить, почему представление контекста не обновляется)

Я получил ту же проблему и решил ее так:

  • Я создал только одно меню (MainMenu.xib). Поскольку пункты меню, для которых первый респондент не предоставляет никаких действий, автоматически выделяются серым цветом, элементы, предназначенные для окна "Документ", будут выделены серым цветом при активации окна "Prefs".

  • Я создал PrefsWin.xib для определения окна prefs. Владельцем файла этой xib является класс с именем PrefsWinController, который наследуется от NSWindowController.

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

Ваш второй NIB будет иметь владельца файла, который вы должны установить в класс, который создается вашим приложением. В этом классе вы можете создать ссылку на делегат приложения, которую можно заполнить при создании экземпляра класса (например, используя setAppDelegate:self если вы создаете его изнутри делегата).

Создайте IBAction в этом классе, который просто передает действие делегату приложения:

- (IBAction) passItOnAction:(id)sender {
    [appDelegate openPreferences:sender];
}
Другие вопросы по тегам