Send An Action Cocoa - IBAction

13,027

Solution 1

controller1 and controller2 are a subclasses of NSControl.

[controller2 sendAction:@selector(receiveAction:) to:controller1];

Solution 2

IBAction is a preprocessor directive that tells Interface Builder "this is something you should know about." It actually evaluates to void. What that means is that the "actions" are just normal methods that you can call in the normal way:

[target someMethod:self];

If you want to mimic the behavior you can get from an NSButton, you can add an outlet for the target and a property for the selector (as a string):

@property (nonatomic, retain) IBOutlet id target;
@property (nonatomic, retain) NSString* actionSelectorString;

Which you could then call like this:

SEL action = NSSelectorFromString(self.actionSelectorString);
[self.target performSelector:action withObject:self];

If you want your class to wire up the selector via drag-and-drop in Interface Builder, the easiest way is to make your class a subclass of NSControl (drag a custom view in from the object library, Command-6 to show inspector, choose your class in the top popup). You can then "call" the action by:

- (void) go {
    [self sendAction:self.action to:self.target];
}

Solution 3

Actions are always received by an object. If you want to send information in the other direction, you probably want an outlet: look for IBOutlet.

Solution 4

NSButton is an NSControl, and thus has an "action" that you can wire up--a message that is sent when you trigger the control (e.g., clicking on a button). A controller doesn't have an action (what would it mean--how would you cause the message to be sent?), so what you are trying to do doesn't actually make sense.

If you want controller2 to be able to have controller1 do something, you should create an outlet on controller2 (of type controller1, or some interface it implements), connect it to controller1 in IB, and then you can send any message you want from controller2 to controller1 programatically.

Solution 5

You should be able to do this if your Controller2 class is a subclass of NSControl. NSControl defines a "sent action" which is what you are connecting to your target object when you drag from NSButton in Interface Builder. That being said, there is (was?) a bug in IB 3.0 that prevented the sent action from showing up in IB. See this cocoa-dev thread for details.

Share:
13,027
Admin
Author by

Admin

Updated on August 04, 2022

Comments

  • Admin
    Admin over 1 year

    I'd like to send an action to another object using cocoa. Ideally i would also like it to appear in the Interface builder.

    I've tried the apple documentation, but there is something i'm missing. Adding the following, the interface building only shows the action as a received one.

    - (IBAction)setTarget:(id)anObject;
    - (IBAction)setAction:(SEL)aSelector;
    

    could someone please give me an example of how to create a sent action. Thanks


    I have the receive action defined in my controller1. I then want my controller2 to be able to send an action to controller1 (like NSButton does). In interface build you can drag a line FROM NSButton to the control that should receive the signal. This functionality can't be limited to just apple objects there, must be a way to do it.

  • kevinthompson
    kevinthompson almost 15 years
    NSSegmentedControl can only send toggle: to an object that accepts that message. aroneous is correct: actions are declared by the receiver, not by the sender.
  • Admin
    Admin almost 15 years
    Yes i have the receive action defined in my controller1. I then want my controller2 to be able to send an action to controller1 (like NSButton does). In interface build you can drag a line FROM NSButton to the control that should receive the signal. This functionality can't be limited to just apple objects there, must be a way to do it.
  • Alex Gray
    Alex Gray about 12 years
    Interface builder is the ultimate Potemkin village. Or maybe more like... A stepford wife. She tries so hard not to let you see whasts going on in there... Then you remember she's a burned out town filled with scary, monkey patched C assembly, etc.
  • ImaginaryCake
    ImaginaryCake about 12 years
    Spoken like someone who's never used any of the other drag-and-drop interface construction tools, which tend to hide a lot more cruft and generate a ton of code that you're not supposed to touch. IB works with ObjC's dynamic runtime to do things that are helpful but not magic; half of what it does is explained above (the other half is setting properties), and that didn't take long at all, did it?
  • Alex Gray
    Alex Gray about 12 years
    I'm being silly… and you're right… even the Xcode-generated assembly is pretty readable and elegant. (Product -> Generate Output -> Assembly File). However, Apple does dance a funny / awkward line between denial / feigning ignorance of the existence of anything anachronistic or unseemingly technical - externally at least. They only lightly-document runtime features they don't want you to know about, etc. It's all reasonable and unoffensive.. but it makes little intricacies of the fun to discuss and learn about, especially since some of it is intentionally forbidden fruit..
  • 11684
    11684 about 11 years
    @alexgray You can read assembly? :O @TALlama you got a typo in your answer: @property ... NSString ... should be @property ... NSString * ... (you forgot the asterisk). But the answer is very helpful!