Каков правильный способ вызвать IBAction с другого контроллера?

#cocoa #objective-c-2.0

#какао #objective-c-2.0

Вопрос:

Речь идет об objective c и cocoa

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

Итак, у меня есть простое окно с 4 элементами:

  1. NSTextField — первое поле для установки значения
  2. NSButton — для установки значения в первом поле
  3. NSTextField — второе поле для установки значения
  4. NSButton — для установки значения во втором поле

вот код «контроллера 1»:

 #import "controller2.h"

@interface controller1 : NSControl{
IBOutlet NSTextField * text1;
}
-(IBAction)click:(id)sender;
@end

@implementation controller1
-(IBAction)click:(id)sender
{
[text1 setStringValue:@"text1 changed"];

// create controller 2 instance
controller2 * c2 = [[[controller2 alloc] init] autorelease];
// call first time using one way
[c2 click:self];

// call second time using another way
[self sendAction:@selector(click:) to:c2];
}
@end
  

и код контроллера 2:

 @interface controller2 : NSControl{
IBOutlet NSTextField * text2;
}
-(IBAction)click:(id)sender;

@end

@implementation controller2
-(IBAction)click:(id)sender
{
[text2 setStringValue:@"text 2 changed"];
NSLog(@"Test2");
}
@end
  

когда я нажимаю на button1, я нажимаю «click» в controller1 — все в порядке и работает правильно

когда я нажимаю на button2, я нажимаю «click» в controller2 — все в порядке и работает правильно

НО если я хочу нажать button1 и нажать «click» в controller2, это не сработает (

Кто-нибудь может помочь с этим? Кажется, у него очень простое решение, но я не знаю, что я сделал не так.

Ответ №1:

 controller2 * c2 = [[[controller2 alloc] init] autorelease];
  

Вы создаете совершенно новый «controller2» (кстати, плохое название для класса — всегда указывайте имена классов с заглавной буквы: «MyController» и т. Д.). Вам нужен IBOutlet от вашего Controller1 к Controller2. Таким образом, вы можете отправлять ему сообщения по имени.

Помните: объекты в nib — это «замороженные» экземпляры классов.

Комментарии:

1. Да, я думаю, вы правы в создании совершенно нового «controller2». Но какой тип IBOutlet я должен написать в controller1? Невозможно создать что-то вроде этого «IBOutlet IBAction * click;».

2. Похоже, вы пытаетесь запустить, прежде чем сможете перейти к разработке Cocoa. Формат «IBOutlet className * outletName;» В вашем случае используйте любое имя вашего класса «controller2». В качестве альтернативы вы можете использовать «IBOutlet id outletName» для «просто любого старого объекта», но лучше всего использовать определенный класс, поскольку он помогает устранить ошибки (и позволяет Interface Builder отфильтровывать неподходящие соединения при попытке их установить).

3. (Повторно) Внимательно прочитайте эту страницу — она проясняет проблемы, с которыми вы боретесь. Один из первых разделов (под названием «Розетки») отвечает на вопрос в вашем комментарии напрямую: developer.apple.com/library/mac/#DOCUMENTATION/Cocoa/Conceptual /…