views:

877

answers:

3

I am looking to create a Custom UIButton (not subclass) progrmatically, I would like it to have a background image that will stretch as the UIButton's width increases. How would I do this?

+2  A: 

First create a stretchable UIImage (this assumes the 'cap' at the end of your button image is 10px):

UIImage *backgroundImage = [[UIImage imageNamed:@"ImageBackground.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];

Then use the stretchable image as the background:

[myButton setBackgroundImage:backgroundImage forState:UIControlStateNormal];

When you set the backgroundImage on a UIButton for UIControlStateNormal, it acts as the background for all states, unless you explicitly set a different backgroundImage for any of the other states.

Nick Forge
I see how this works but for some reason the code I'm using (http://gist.github.com/378341) doesn't add anything to the view. My redButton.png file is in my resources.
Joshua
Check (using the debugger or using `NSLog`) that your `backgroundImage` isn't nil. If `+[UIImage imageNamed:]` can't find your image, it will return nil.
Nick Forge
Minor nit: `-stretchableImage…` accepts 2 integers as input, not floating points.
KennyTM
@Nick I've set up an NSLog like this: ` NSLog(@"background: %d", backgroundImage);` and it prints `background: 0`.
Joshua
@KennyTM: thanks for spotting that. Edited to fix. @Joshua: in that case, for some reason `UIImage` can't find your image. Make sure that an image with that _exact_ name (it's case-sensitive) is in your Xcode Project, not just in your Xcode Project's folder. To add an image to your project, drag it from the Finder into the Project window.
Nick Forge
That's odd as the image is in the resources folder of my XCode Project and has the exact same name as I typed. http://unmd.ausgat.com/files/maccrystal/ad.Screen%20shot%202010-04-25%20at%2016.10.41.png
Joshua
Why wouldn't it be able to find it?
Joshua
Try removing it from your project then re-adding it. If that doesn't work, verify that the image isn't corrupt, and that it is actually a PNG file, not a JPEG file. Try looking for your image in the Media section of IB - if it's not there, it's either corrupt or not loaded in your project properly.
Nick Forge
So, I've checked all those things. But here's what interesting, I have set the background of a UIButton to redButton.png in IB but when I run the app it's not displayed. The debugger gives me this error: `Could not load the "redButton.png" image referenced from a nib in the bundle with identifier "com.yourcompany.MYAPP"`
Joshua
I've seen this before a few times, but it has always been either an image that was corrupted (or had the wrong extension), or hadn't been added into the project bundle properly somehow. The only things I can suggest are to try and open the PNG in Preview.app and do a Save As to ensure there's no corruption, and then try removing the image from your project, doing a Clean of your project, then re-adding the newly saved PNG and building again. Good luck.
Nick Forge
Saving as worked! Thanks very much!
Joshua
A: 

You have to set an UIImage created with the "stretchableImageWithLeftCapWidth:topCapHeight:"-Method as button background. For example:

UIImage *yourBackgroundImage = [[UIImage imageNamed:@"yourImage.png"] stretchableImageWithLeftCapWidth:1 topCapHeight:1];
yourButton.backgroundColor = [UIColor colorWithPatternImage:yourBackgroundImage];
Blauesocke
A: 

Better yet, use UIView's contentStretch property. Otherwise, you might get some nasty surprises if you use stretchableImageWithLeftCapWidth to shrink a graphic or to stretch a complex graphic with lighting or gloss effects.

Rolf Hendriks