Создание вложенного NSMenu из NSDictionary

Я создал NSDictionary, содержащий несколько вложенных слоев, и я хочу воспроизвести его как NSMenu, чтобы при обновлении моего NSDictionary обновлялся и мой NSMenu. Например, если у меня есть NSDictionary, содержащий:

Item1
 |---Item 1.1
 |---Item 1.2

Item2
 |---Item 2.1
 |    |---Item 2.1.1
 |---Item 2.2
 |---Item 2.3 

Item3

Это должно привести к тому, что мое меню будет состоять из трех пунктов: Пункт 1, Пункт 2 и Пункт 3. Пункт 1 и Пункт 2 должны быть подменю, как и Пункт 2.1 и так далее.

Если я удалю пункт 2, то пункт 2 и все его подменю также должны быть удалены.

Проблема в том, что я понятия не имею, как к этому подступиться. Я знаю, как сделать NSMenu программно, поэтому я не подхожу к этому без каких-либо знаний, но у меня нет первой идеи, как имитировать привязку таким образом.

Любая помощь будет принята с благодарностью.


person headbanger    schedule 15.02.2013    source источник
comment
Можете ли вы объяснить, почему вы постоянно хотите манипулировать меню через NSDictionary? У меня небольшие проблемы с пониманием смысла упражнения, поэтому я чувствую, что любой ответ, который я дал, вероятно, также не будет иметь смысла.   -  person Chuck    schedule 15.02.2013
comment
@Chuck Я пытаюсь представить все устройства в USB-дереве компьютеров в меню. Поэтому, когда дерево USB изменяется (например, добавляется или удаляется устройство), меню обновляется соответствующим образом. Item1 в примере будет контроллером 1, Item 1.1 — первым устройством, подключенным к этому контроллеру, и так далее. Я пытался «обобщить» свой пример, чтобы сделать его максимально полезным.   -  person headbanger    schedule 01.03.2013


Ответы (1)


Это можно сделать, настроив объект в качестве делегата меню (см. NSMenuDelegate). Я устанавливаю для тега пункта меню уникальное значение, а затем нахожу этот пункт меню во время запуска. Я использую App Delegate в качестве делегата меню, а затем создаю меню, реализуя следующие методы делегата:

- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu;

- (BOOL)menu:(NSMenu *)menu
  updateItem:(NSMenuItem *)item
     atIndex:(NSInteger)index
shouldCancel:(BOOL)shouldCancel;

У вас есть дополнительное усложнение произвольно сложной структуры словаря, поэтому вам нужно создать собственный класс для хранения каждого элемента меню (текст меню и селектор в виде строки, а также все, что вам может понадобиться). Затем сохраните эти элементы и любые подсловари в основном словаре.

Когда вы приступите к перечислению словаря (в методе делегата menu:updateItem:atIndex:shouldCancel:), вам нужно будет проверить тип объекта (пользовательский объект или словарь) с помощью isKindOfClass, а для того, чтобы иметь дело с произвольной вложенностью, вы, вероятно, захотите использовать частный, рекурсивный , метод, который работает с одним словарем.

Удачи; это не просто, но, безусловно, достижимо.

person trojanfoe    schedule 15.02.2013
comment
Ух ты! Это звучит как очень умное и эффективное решение. Увы, я понятия не имею, как к этому подойти... Какой-нибудь пример кода? Учебники? Что-то, что даст мне рычаг и заставит меня начать? - person headbanger; 16.02.2013
comment
@headbanger Образец Apple SidebarDemo, похоже, использует NSMenuDelegate developer.apple.com/library/mac/ образец кода/демонстрация боковой панели - person trojanfoe; 16.02.2013