views:

1998

answers:

5

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.

A: 

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.

Aron
How do buttons e.g. NSSegmentedcontrol send toggle: then?
Ben Reeves
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.
Kristopher Johnson
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.
Ben Reeves
A: 

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.

smorgan
A: 

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.

e.James
A: 

controller1 and controller2 are a subclasses of NSControl.

[controller2 sendAction:@selector(receiveAction:) to:controller1];
Mark Thalman
+2  A: 

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];
}
TALlama