With the introduction of iOS 5 the gods that are the iOS framework engineers have given us the wonderful gift of UIAppearence. The new appearance proxies allow us developers to customise the look and feel of our applications, such as Navigation Bars, Toolbars and Tab Bars without swizzling or naughty categories.
The following is a REALLY brief overview of what @ctp went into in his WWDC’11 talk which you can watch online here (if you’re an apple developer and logged into developer.apple.com)
The new appearance proxies let us call methods such as setBackgroundImage: forBarMetrics: on our bars and bar button items so we can really give our apps a good polishing up. Normally we’d call these methods as follows:
[myToolbar setBackgroundImage:myUIImage forBarMetrics:UIBarMetricsDefault];
So very simple, and all these methods are now fully documented. There are very slight variations in the appearance methods per control so it it worth referring to the documentation to save a headache or two when things don’t go right.
Not only can you set appearance properties for instances of classes, you can set them for a class in general. Think how your categories worked. You can change the appearance of UINavigationBar across you entire app in one swoop:
[[UINavigationBar apperence] setBackgroundImage:… forBarMetrics:…];
Many UIKit classes now have an appearance property. This passes back the appearance proxy for that class, and once you’ve made changes any instance of that class from the point of you modified the appearance will look sexy. If you create an instance of a control before you modify the appearance proxy you must re-initialise/redraw that instance for modifications to take effect.
One more thing. So you know how to modify the appearance of a single instance as well as the appearance for all instances of that class. But you can also define specific appearance properties depending on what the control is contained in. For example, if I wanted to change a navigation bar’s appearance solely when it’s present in MyViewController I would do so like this:
[[UINavigationBar apperenceWhenContainedIn:[MyViewController class], nil] …];
Really simple eh? Instead of calling appearance you simple specify a nil terminated list of containers for which these changes should take effect in.
This new addition to iOS now means you shouldn’t have to write another swizzle or category for simply prettify your bars and buttons.