In our apps I often need to load images for UI elements like buttons. There are several variants of each image, like landscape/portrait, disabled/enabled, pushed/regular and even colors like white/red/gray. The loading code has some variables that tell it which variant to load. As an example, take a look at the following sample button class:
enum {
SampleImageButtonRed,
SampleImageButtonWhite
} SampleImageButtonStyle;
@interface SampleImageButton : NSObject
@property(assign) SampleImageButtonStyle style;
@property(assign) BOOL landscape;
@property(assign) BOOL disabled;
@property(assign) BOOL pushed;
@end
Here the loading code has to peek at the properties and load button_white_pushed.png
, button_red_landscape.png
and so on, according to the button type. The code is conceptually simple (just some string formatting and [UIImage imageNamed:]
calls), but at the same time there’s a lot of noise and boilerplate.
I’ve tried to think of a simple helper class that would make this easier. The class would take the rules mapping the properties to the resulting image name, then it would take the actual property values at hand and return the appropriate image. Something like:
ImageBuilder *builder = [[ImageBuilder alloc] init];
[[[builder record] setPathTag:@"button_red"] setButtonStyle:SampleImageButtonRed];
[[[builder record] setPathTag:@"button_white"] setButtonType:SampleImageButtonWhite];
[[[builder record] setPathTag:@"disabled"] setDisabled:YES];
[[[builder record] setPathTag:@"enabled"] setDisabled:NO];
[[[builder record] setPathTag:@"landscape"] setLandscape:YES];
[[[builder record] setPathTag:@"portrait"] setLandscape:NO];
And then I would call something like this:
// would load “button_red_enabled.png”
UIImage *texture = [[[builder image]
setButtonStyle:SampleImageButtonRed]
setDisabled:NO];
At this moment I’m not interested in whether the added complexity is worth it, I’m interested in the API design and implementation. I think the “recording” API could work, but the “query” API doesn’t, since setButtonStyle:
returns void
and therefore I can’t chain the calls or return the image.
Do you have ideas for a nice generic API for this problem that could work?