Почему я не могу подключить свое меню к контроллеру представления IBAction?

У меня есть приложение на основе документов. Я только что создал пункты меню в раскадровке и IBActions в моем контроллере представления. Однако обычный способ подключения действия к цели не работает

-(IBAction) markAsHidden:(id)sender;
-(IBAction) markAsVisible:(id)sender;
-(IBAction) toggleHidden:(id)sender;

Вот что я вижу, когда из своего пункта меню я нажимаю Ctrl и щелкаю мышью от меню до View Controller. Это не показывает мои IBActions.

Любая идея? Мои 2 цента предполагают, что это связано с приложением, основанным на документе, но... не совсем уверен

меню подключения

3 ответа

Решение

Почему я не могу подключить свое меню к контроллеру представления IBAction?

Потому что ваши пункты меню и контроллер представления находятся в разных сценах в раскадровке. Вы можете думать о сцене как о независимом графе объектов, которые создаются при загрузке сцены из раскадровки. Объекты в разных сценах не могут быть соединены вместе в раскадровке, потому что они не загружены одновременно.

Просто для удовольствия, попробуйте создать экземпляр вашего контроллера представления в сцене приложения в вашей раскадровке. Чтобы сделать это, вам, вероятно, нужно будет перетащить простой старый NSObject экземпляр в сцену, а затем установить его тип. Как только вы это сделаете, вы обнаружите, что можете перетащить соединение из пункта меню в этот контроллер представления так, как вы ожидаете, но вы не можете перетащить соединение в другой объект того же типа в другом сцена.

Примечание. Как только вы поиграете достаточно, чтобы убедиться, что это работает, не забудьте удалить контроллер представления, который вы добавили. Контроллер представления без представления подобен утке без шарлатана, и контроллер представления и его иерархия представления должны быть в их собственной сцене.

Мои 2 цента предполагают, что это связано с приложением, основанным на документе

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

Как уже было сказано Марком, простое решение - использовать цепочку респондента. Прокси-объект First Responder является частью каждой сцены, поэтому вы всегда можете установить с ним связь. Когда вы подключаете пункт меню к First Responder, его цель будет nil, который говорит NSMenu пройтись по цепочке респондента, пока не найдет объект, который отвечает на сообщение действия пункта меню. Затем он отправляет сообщение этому объекту.

Подключите пункты меню к первому ответчику сцены приложения. Когда вы подключаетесь к первому респонденту сцены приложения, IBActions вашего контроллера представления должны появиться в списке доступных действий HUD, а не в последовательностях действий, показанных в HUD вашего скриншота.

Если вы конвертируете проект из цели C в Swift, не делайте мою ошибку. При написании вашего IBAction напишите так:

 @IBAction func someAction(_ sender:AnyObject) {
     // this will work
 }

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

 @IBAction func someAction(sender:AnyObject) {
     // this won't work and IB won't connect to this action
     // because sender will be part of the symbol name
 }
Другие вопросы по тегам