How to create a pixel-perfect UIBarButtonItem of *any* color

One of the first big run-ins I had with the iOS SDK came in my first app, Chela's Tacos.  I wanted to be able to create a UIBarButtonItem that had a different tint to it than it's enclosing UIToolbar.  This proved a frustrating affair because there is no API for directly changing the button's tint: it always takes on a similar hue to its toolbar.  Today that has changed.

While poking around a class dump of the private APIs for the iOS SDK, I stumbled upon what a UIBarButtonItem is.  It's really just a class that composes what is called a UIToolbarItem and a few other attributes and methods.  This is very interesting in and of itself, but I found a way to be able to change its color.  This is really nice and everything, except I had to use private API to change it.  This means that any use of it would more than likely end getting your app rejected because of the use of those private APIs.  Let's just say I found a tenable work-around.

Instead of trying to use the private API or having to painstakingly try and reproduce the button in Photoshop, I decided to take the UIBarButtonItem and write it to a graphics context and write the image to disk.  In this way, I could create a pixel-perfect, but stretchable image that would look and behave just like a UIBarButtonItem programmatically created by the SDK.  Once I discovered how easy it was to do this, I decided to write a little iOS app that would allow me to select any color I wished using a set of RGB controls:

I have decided to make the code available here.  Please note that it is very rough and likely has a lot of bugs, but it does make pixel perfect images of the UIBarButtonItem.  In fact, if you load this up in the retina display iPhone simulator, you'll get the 2x images. Also: DO NOT use this code to change the color in your App Store application. More than likely it will get rejected, so don't do it.

For best results, don't set any button text.  You want to be able to reuse the button with any text on it, so it works best to stretch the image.  All you have to do is set the desired color and then tap the Save button. This app will create both the Retina Display and standard images and the normal and pressed state.

Posted on Apr 4
Written by Wayne Hartman