PDA

View Full Version : Create button programmatically




SRossi
Jul 6, 2009, 01:23 PM
Hi all,

Me yet again with another question. What I'm trying to do now is create a button programmatically with a custom picture as the front of the button.

Any guides or examples or places to look will be appreciated.

Thanks again,

Stephen



robbieduncan
Jul 6, 2009, 01:45 PM
NSButton (http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSButton_Class/Reference/Reference.html)


NSButton *myButton = [[NSButton alloc] initWithFrame:NSMakeRect(0,0,100,100)];
[myButton setImage:myImage];


Should create a 100x100 button (at 0,0 initially) with image set to myImage (a NSImage you have to deal with creating)...

Edit to add: not I just typed this straight into the reply: it could be buggy. Also this won't actually show a button anywhere: you need to add it as a subview to a view in a window.

SRossi
Jul 6, 2009, 02:23 PM
Right thanks :) got a button set up but now how will I set up the button to call another window when pressed?

This window has already be connected to another outlet. Can I call the original method to call the other window if so how would this be done?

Thanks,

Stephen

robbieduncan
Jul 6, 2009, 03:35 PM
Use setTarget:/setAction: to set the target object (should be in the controller, not the view layer so not directly a NSWindow, rather something in your controller layer that will update the model layer which will then cause your view to update via the controller layer) and the action (the method that will be executed on the target object). Basically this is the same as dragging in IB and choosing the method to execute.

SRossi
Jul 6, 2009, 06:17 PM
Use setTarget:/setAction: to set the target object (should be in the controller, not the view layer so not directly a NSWindow, rather something in your controller layer that will update the model layer which will then cause your view to update via the controller layer)

Can you explain what you mean by this because im not understanding what you are meaning, like should it be the target of a window controller?

the action (the method that will be executed on the target object)

What I have done for this is :

[myButton setAction:[self changeWindow:self]];


It does not give an error but says "Invalid use of void expression", this peice of code is in the awakeFromNib function. changeWindow is the function used to change the windows.

Thanks for your help :)

Stephen

robbieduncan
Jul 7, 2009, 02:53 AM
The target should be a valid instance in the controller layer. The NSWindowController subclass that owns this window is a decent idea.

The action is not an invoked method (which is what you have) rather a description of the method. Something like:


[myButton setTarget:self]; // Sets the target of the action to this object
[myButton setAction:@selector(handleButton:)]; // Sets the action

....

-(void) handleButton:(id) sender
{
// Handle button click here
}


Again this is just typed straight into MR: it may have typos.

SRossi
Jul 7, 2009, 09:39 AM
Thanks Robbie for showing how to set the target and action, but I decided to go back and look at using an icon for the button but when my code is:

[myButton setAlternateImage:@"FSInfo.tif"];

all it does is create a button without anything in it, am I missing anything out? FSInfo.tif has been added to the Resources folder of the project in Xcode.

Thanks,

Stephen

robbieduncan
Jul 7, 2009, 09:42 AM
Thanks Robbie for showing how to set the target and action, but I decided to go back and look at using an icon for the button but when my code is:

[myButton setAlternateImage:@"FSInfo.tif"];

all it does is create a button without anything in it, am I missing anything out? FSInfo.tif has been added to the Resources folder of the project in Xcode.

Thanks,

Stephen

You need to learn to read the documentation carefully. The signature of that method is:

- (void)setAlternateImage:(NSImage *)image

You are trying to call

- (void)setAlternateImage:(NSString *)image

You need to actually load the image...

SRossi
Jul 7, 2009, 10:21 AM
Right have changed my code again, taking into account what you have said so it now looks like:

NSString *imageName = [[NSBundle mainBundle] pathForResource:@"FSInfo.tif" ofType:@"TIF"];
NSImage *tempImage = [[NSImage alloc] initWithContentsOfFile:imageName];
[myButton setImage:tempImage];
[myButton setImagePosition:NSImageOnly];

But now it just shows a blank button again, without the NSImageOnly it included a string of "button" though.

I'm thinking im missing something but looking through the documentation it should work?

Thanks again,

Stephen

robbieduncan
Jul 7, 2009, 10:25 AM
Just guessing here but you are not a professional programmer? Just learning? Because you should check that the objects being returned are actually what you expect. And once again read the documentation!

I would expect that imageName is nil as you are asking for resource FSInfo.tif of type TIF which, as per the example in the documentation (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/nsbundle_Class/Reference/Reference.html#//apple_ref/occ/instm/NSBundle/pathForResource:ofType:) you should not be doing. Also, as per the documentation, you should check for the returns to most of these calls being nil.

Please, read the documentation, do the sensible sanity checks (nil objects, compiler warnings etc) before asking questions!

SRossi
Jul 7, 2009, 10:40 AM
Ah ha cracked it, thank you Robbie for all your help so far. And sorry if I have been a nuisance to you.

Setting the image turned out harder than I would have ever believed but its made me understand bundles better.

Thanks Robbie again.

Stephen