Making UIBarButtonItems in Photoshop
Recently I was working on an app that required brightly tinted tool bars and navigation bars:
As you can see, the light blue color makes the bar button hard to see and its label hard to read. Changing the background color of the button is really easy on iOS 5 because its UIBarButtonItem also has a .tintColor property. But if you still need to support iOS 4 then you’re out of luck.
In that case, the only solution is to put a UIButton inside the UIBarButtonItem and give it a background image that looks like a regular bar button. It’s a roundabout way of doing things but it works.
Previously, I would draw these bar button-lookalike images myself in Photoshop. By setting the appropriate layer styles on a rounded rectangle vector object you can make a decent approximation of what a real bar button item looks like.
This time, however, I wanted to take advantage of the actual images that UIKit itself uses to compose the UIBarButtonItem when you change the tintColor of the underlying toolbar or navigation bar.
To pull this off, you can download UIKit Artwork Extractor. Compile the app and run it on the Simulator (or on your device). It will extract all the images that are built into the various iPhone and iPad frameworks and save them to a folder on your computer.
After you have extracted the images, go into the “Shared” subfolder and look for:
- UITintedButtonHighlight.png
- UITintedButtonMask.png
- UITintedButtonShadow.png
You can combine these three images with a fill color to produce a tinted UIBarButtonItem background image, like this:
The actual layers pane should look like this:
The “Fill color” layer is simply a rectangle filled with the tint color that you want the button to have. As you can see, both the fill layer and the “shadow” layer are clipped against the red “mask” layer. If you don’t do that, the button won’t have a transparent background in the corners.
To export the image, merge all the visible layers (but not the background!) and save the image as PNG. This gives you a 11×30 pixels stretchable image.
You can use the following category to create the fake bar button items in your code. It requires that the image named “BarButton.png” is added to your project.
@implementation UIBarButtonItem (FakeButtons) - (id)initWithTitle:(NSString *)title width:(CGFloat)width target:(id)target action:(SEL)action { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setTitle:title forState:UIControlStateNormal]; [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; button.titleLabel.font = [UIFont boldSystemFontOfSize:12]; button.titleLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.5]; button.titleLabel.shadowOffset = CGSizeMake(0, -1); button.frame = CGRectMake(0, 0, width, 30); UIImage *image = [[UIImage imageNamed:@"BarButton"] stretchableImageWithLeftCapWidth:5 topCapHeight:0]; [button setBackgroundImage:image forState:UIControlStateNormal]; return (self = [self initWithCustomView:button]); } @end |
In the “Shared” folder you will also find images for the UINavigationController back button (named UITintedBackButtonXXX.png), but be advised that bar button items with a custom view won’t work on UINavigationItem’s backBarButtonItem property. You’ll have to put your custom back button on leftBarButtonItem instead.
Tip: If you also want to have Retina-sized images, run Artwork Extractor on a Retina device or on the Simulator in Retina mode. It’s very enlightening to look through the rest of the extracted artwork as well.




