Как соединить пункт меню с пользовательским действием, определенным в делегате NSApplication через файлы пера? - PullRequest
3 голосов
/ 13 сентября 2011

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

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

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

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

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

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

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

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

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

Ответы [ 4 ]

3 голосов
/ 13 сентября 2011

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

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

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

1 голос
/ 04 апреля 2014

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

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

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

0 голосов
/ 28 июля 2013

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

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

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

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

0 голосов
/ 13 сентября 2011

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

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

- (IBAction) passItOnAction:(id)sender {
    [appDelegate openPreferences:sender];
}
...