Create button programmatically

Discussion in 'Mac Programming' started by SRossi, Jul 6, 2009.

  1. macrumors regular

    Joined:
    May 27, 2009
    Location:
    Glasgow, Scotland
    #1
    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
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    NSButton

    Code:
    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.
     
  3. thread starter macrumors regular

    Joined:
    May 27, 2009
    Location:
    Glasgow, Scotland
    #3
    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
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    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.
     
  5. thread starter macrumors regular

    Joined:
    May 27, 2009
    Location:
    Glasgow, Scotland
    #5
    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?

    What I have done for this is :

    Code:
    [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
     
  6. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    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:

    Code:
    [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.
     
  7. thread starter macrumors regular

    Joined:
    May 27, 2009
    Location:
    Glasgow, Scotland
    #7
    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:

    Code:
    [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
     
  8. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    You need to learn to read the documentation carefully. The signature of that method is:

    Code:
    - (void)setAlternateImage:(NSImage *)image
    You are trying to call

    Code:
    - (void)setAlternateImage:(NSString *)image
    You need to actually load the image...
     
  9. thread starter macrumors regular

    Joined:
    May 27, 2009
    Location:
    Glasgow, Scotland
    #9
    Right have changed my code again, taking into account what you have said so it now looks like:

    Code:
    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
     
  10. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #10
    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 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!
     
  11. thread starter macrumors regular

    Joined:
    May 27, 2009
    Location:
    Glasgow, Scotland
    #11
    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
     

Share This Page