Добавление элемента в NSMenu с предустановкой селектора действий

Я новичок в программировании Obj-C / Cocoa, и у меня возникла проблема с попыткой динамически добавлять элементы меню в экземпляр NSMenu и установить селектор действий элементов при вставке.

Я могу добавить элементы динамического меню нормально, но селектор действий не срабатывает, когда элемент щелкается через меню.

Первая строка ниже - это строка кода, которую я использую для добавления пункта меню. Вы можете установить Я устанавливаю действие: (SEL) aSelector на функцию "openEchowavesURL".

Эта функция находится в том же файле класса контроллера, и я включил определение функции ниже.

Я просто вызываю неправильный синтаксис селектора или что-то еще? Или как заставить пункт меню вызывать селектор при нажатии?


[statusMenu insertItemWithTitle:[NSString stringWithFormat:@"%d - %@", convo.newMessagesCount, convo.ewName] action:@selector(openEchowavesURL:) keyEquivalent:@"" atIndex:0];

- (void)openEchowavesURL:(id)sender {
    // function details here
}

person cpjolicoeur    schedule 28.12.2009    source источник


Ответы (2)


Если вы хотите, чтобы действие запускалось для вашего объекта, вы должны указать цель для нового NSMenuItem:

NSMenuItem *item = [statusMenu insertItemWithTitle:[NSString stringWithFormat:@"%d - %@", convo.newMessagesCount, convo.ewName] action:@selector(openEchowavesURL:) keyEquivalent:@"" atIndex:0];
[item setTarget:self]; // or whatever target you want

Если вы этого не сделаете, тогда NSResponder будет проходить до тех пор, пока объект не ответит на селектор.

person Laurent Etiemble    schedule 28.12.2009
comment
благодаря. Итак, если цепочка пройдена, почему селектор не найден в моем текущем классе контроллера? Почему в таком случае мне нужно вручную указывать себя? - person cpjolicoeur; 28.12.2009
comment
Вы должны соответствовать определенным критериям, чтобы вас опрашивали во время поиска. Я предлагаю вам прочитать следующее руководство, чтобы понять, как: developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ - person Laurent Etiemble; 28.12.2009
comment
Ваш контроллер, вероятно, не является частью цепочки респондентов. - person Azeem.Butt; 28.12.2009
comment
В любом случае классы, как правило, не являются контрольными объектами. Респонденты - это экземпляры. Ваш объект может реагировать на селектор, но если он не входит в цепочку респондентов и вы не устанавливаете цель элемента управления специально для своего объекта, то сообщение никогда не попадет в ваш объект. Решение состоит в том, чтобы либо сделать ваш объект респондентом и сохранить его в цепочке респондентов, либо установить цель элемента управления для вашего объекта. - person Peter Hosey; 29.12.2009

Действиям нужна цель, иначе они будут сброшены на ноль, а затем применяются новые правила.

person Azeem.Butt    schedule 28.12.2009
comment
Вы можете объяснить это поподробнее? Не думаю, что понимаю. Я устанавливаю действие для селектора, который мне нужен для вставляемого пункта меню. Что еще мне нужно сделать для постановки цели? - person cpjolicoeur; 28.12.2009
comment
Отправьте элементу сообщение setTarget. - person Azeem.Butt; 28.12.2009
comment
Если вы отправляете действие в nil (NULL), то будет использоваться firstResponder (когда это возможно). В сортировке: чтобы позволить самому переднему окну обрабатывать действие, установите для цели значение NULL. В Интерфейсном Разработчике вы добавляете действия к классу FirstResponder, а затем подключаете действия непосредственно к экземпляру firstResponder, а не к вашим собственным объектам. -Слишком часто бывает хорошей идеей (особенно для пунктов меню) установить цель в NULL. Помните, что вы также можете использовать representedObject для хранения ссылок на данные / объекты. - person ; 21.11.2014