10

I'm making a couple of buttons programmatically and trying to set an action to each but I can't seem to get it to work.

In my AppController.h I have this code:

...
IBOutlet NSButton* btnZoomIn;
IBOutlet NSButton* btnZoomOut;
...

and

- (IBAction) zoomIn : (id) sender; 

- (IBAction) zoomOut : (id) sender;

and in AppController.m within the awakeFromNib method:

/*zoom in and out buttons*/

//get the path to the image files
NSString* zoomInImgPath = [[NSBundle mainBundle] pathForResource:@"zoomIn" ofType:@"png"];
NSString* zoomOutImgPath = [[NSBundle mainBundle] pathForResource:@"zoomOut" ofType:@"png"];

//declare the NSImages
zoomInImg = [[NSImage alloc] initWithContentsOfFile:zoomInImgPath];
zoomOutImg = [[NSImage alloc] initWithContentsOfFile: zoomOutImgPath];

//button making!
//zoomIn
btnZoomIn = [[NSButton alloc] initWithFrame:NSMakeRect(1426.0, 920.0, 25.0, 25.0)];
[btnZoomIn setButtonType:NSMomentaryPushInButton];
[btnZoomIn setTitle:@""];
[btnZoomIn setToolTip:@"Zoom In"];
[btnZoomIn setImage:zoomInImg];
[btnZoomIn setAction:@selector(zoomIn:)];
[[mainWin contentView] addSubview:btnZoomIn];

//zoomOut
btnZoomOut = [[NSButton alloc] initWithFrame:NSMakeRect(1456.0, 920.0, 25.0, 25.0)];
[btnZoomOut setButtonType:NSMomentaryPushInButton];
[btnZoomOut setTitle:@""];
[btnZoomOut setToolTip:@"Zoom Out"];
[btnZoomOut setImage:zoomOutImg];
[btnZoomOut setAction:@selector(zoomOut:)];
[[mainWin contentView] addSubview:btnZoomOut];

and

- (IBAction) zoomIn : (id) sender  { 
    NSLog(@"zoom in!");
 }

 - (IBAction) zoomOut : (id) sender { 
    NSLog(@"zoom out!");
 }

but zoomOut and zoomIn do not get hit...

PruitIgoe
  • 6,166
  • 16
  • 70
  • 137

4 Answers4

30

The most likely reason is that there’s no object in the responder chain for action messages responding to those actions. When you specify an action but don’t specify a target, Cocoa tries to find an object that responds to those action messages by traversing the responder chain.

Either make sure that you have a suitable object in the responder chain or, if you have a reference to that object, specify it as the target of those actions:

[btnZoomIn setAction:@selector(zoomIn:)];
[btnZoomIn setTarget:objectThatRespondsToZoomIn];

[btnZoomOut setAction:@selector(zoomOut:)];
[btnZoomOut setTarget:objectThatRespondsToZoomOut];
2

Another cause of the issue could be that the button (or the containing class that creates the button (or the containing class that creates the containing class that creates the button)) is not stored and goes out of scope.

If you call onClick() on the button in i.e. viewDidLoad and that works, but manually clicking the button afterwards doesn't then this is your problem.

Yasper
  • 501
  • 5
  • 23
1

I couldn't figure out why my setAction wasn't working even with setTarget.

The issue was I had subclassed NSButton and overrode onMouseDown and forgot to call super.onMouseDown

Adam Johns
  • 35,397
  • 25
  • 123
  • 176
0

Add:

[btnZoomIn setTarget:self];
[btnZoomOut setTarget:self];
Akshay Phulare
  • 1,359
  • 2
  • 10
  • 15