iOS developers deeply know the huge value of working with a good graphic designer. Providing assets with the correct size, for all needed states, for any type of device, with good naming conventions etc. are things that you probably appreciate a lot and make the whole development process faster and efficient. Therefore, it is also the developer responsibility to provide tools to increase the development process and make the UI customization more agile and easy to the designer. For this reason, in this post we are introducing some ideas that will decrease the amount of graphic assets you need, add flexibility to change colors and much more.

Resizable Plain-Color Images

iOS7 introduced new design guidelines that include plain-color style and flat design. This is a huge simplification of each graphic asset: no shadows, single colors, no deepness-effect, etc. Consequently, in order to customize the UINavigationBar, UIButton, backgrounds of your views, etc. we could create resizable images of plain-color (or even gradients) dynamically. This means we can define colors programmatically and change them whenever we want. To achieve this, an option is to create a category on UIImage that would provide tools for this purpose:

@interface UIImage (Additions) + (UIImage*)imageWithColor:(UIColor*)color size:(CGSize)size; + (UIImage*)imageWithColor:(UIColor*)color size:(CGSize)size cornerRadius:(CGFloat)cornerRadius; + (UIImage*)resizableImageWithColor:(UIColor*)color; + (UIImage*)resizableImageWithColor:(UIColor*)color cornerRadius:(CGFloat)cornerRadius; @end 1 2 3 4 5 6 7 8 9 @interface UIImage ( Additions ) + ( UIImage * ) imageWithColor : ( UIColor * ) color size : ( CGSize ) size ; + ( UIImage * ) imageWithColor : ( UIColor * ) color size : ( CGSize ) size cornerRadius : ( CGFloat ) cornerRadius ; + ( UIImage * ) resizableImageWithColor : ( UIColor * ) color ; + ( UIImage * ) resizableImageWithColor : ( UIColor * ) color cornerRadius : ( CGFloat ) cornerRadius ; @end

Therefore, some examples of usage:

// Customizing background image of UIButton UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setTitle:@"MyAction" forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage resizableImageWithColor:[UIColor redColor] cornerRadius:5] forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage resizableImageWithColor:[UIColor blueColor] cornerRadius:5] forState:UIControlStateHighlighted]; // Customizing navigation bar appearance [[UINavigationBar appearance] setBackgroundImage:[UIImage resizableImageWithColor:[UIColor greenColor]] forBarMetrics:UIBarMetricsDefault]; 1 2 3 4 5 6 7 8 9 // Customizing background image of UIButton UIButton *button = [ UIButton buttonWithType :UIButtonTypeCustom ] ; [ button setTitle : @"MyAction" forState :UIControlStateNormal ] ; [ button setBackgroundImage : [ UIImage resizableImageWithColor : [ UIColor redColor ] cornerRadius : 5 ] forState :UIControlStateNormal ] ; [ button setBackgroundImage : [ UIImage resizableImageWithColor : [ UIColor blueColor ] cornerRadius : 5 ] forState :UIControlStateHighlighted ] ; // Customizing navigation bar appearance [ [ UINavigationBar appearance ] setBackgroundImage : [ UIImage resizableImageWithColor : [ UIColor greenColor ] ] forBarMetrics :UIBarMetricsDefault ] ;

Having this tool, the graphic designer won’t have to provide anymore plain-color background images and we will have more flexibility to customize our UI objects.

Tinting images

Another typical case is when we have a graphic asset that needs multiple versions of it for the different states (typically UIControl states as default, highlighted, selected, disabled, etc.). Usually, the graphic designer must provide one asset per each state of the image. This implies that if some design guidelines change in the app you are working, those images for each state will have to be updated (for example: if the color that represents “highlighted” state changes). A solution for this problem is to dynamically tint images. This is much simpler for everyone: the designer will only provide one image and the application in run time will “tint” the image to a custom color for each needed state. Also, by using this approach, because colors are defined programmatically, we can change them without any extra work. iOS 7 introduced tools for tinting images that are rendered inside a UIImageView:

UIImage *image = [UIImage imageNamed:@"IMAGE_NAME"]; // image to be rendered UIImageView *imageView = ... // your UIImageView instance imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; imageView.tintColor = [UIColor redColor]; 1 2 3 4 5 UIImage *image = [ UIImage imageNamed : @"IMAGE_NAME" ] ; // image to be rendered UIImageView *imageView = . . . // your UIImageView instance imageView . image = [ image imageWithRenderingMode :UIImageRenderingModeAlwaysTemplate ] ; imageView . tintColor = [ UIColor redColor ] ;

However, it might be more useful (also for previous versions of iOS) to use a custom method on UIImage:

@interface UIImage (Additions) + (UIImage*)imageNamed:(NSString *)name tintColor:(UIColor*)color; - (UIImage*)tintedImageWithColor:(UIColor*)color; @end 1 2 3 4 5 6 @interface UIImage ( Additions ) + ( UIImage * ) imageNamed : ( NSString * ) name tintColor : ( UIColor * ) color ; - ( UIImage * ) tintedImageWithColor : ( UIColor * ) color ; @end

Therefore, this category would be used as it follows:

// Setting different images for each needed state on UIButton UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setImage:[UIImage imageNamed:@"myImage" tintColor:[UIColor blueColor]] forState:UIControlStateNormal]; [button setImage:[UIImage imageNamed:@"myImage" tintColor:[UIColor redColor]] forState:UIControlStateHighlighted]; 1 2 3 4 5 // Setting different images for each needed state on UIButton UIButton *button = [ UIButton buttonWithType :UIButtonTypeCustom ] ; [ button setImage : [ UIImage imageNamed : @"myImage" tintColor : [ UIColor blueColor ] ] forState :UIControlStateNormal ] ; [ button setImage : [ UIImage imageNamed : @"myImage" tintColor : [ UIColor redColor ] ] forState :UIControlStateHighlighted ] ;

More information about how to implement this category will be found at the end of the post.

Composing images

Finally, lets take a look on making compositions of different images on the fly. This would be useful to create versions of images that are already in our bundle. For example, a blue tinted image X and a red tinted image Y over a green background with corner radius. This way, only by reusing already existing assets we could be able to create a completely new set of images to customize our UI. A simple category on UIImage as it follows would do the job:

@interface UIImage (Additions) - (UIImage *)imageAddingImage:(UIImage*)image; // adds image in the centre - (UIImage *)imageAddingImage:(UIImage*)image offset:(CGPoint)offset; // add image with custom offset @end 1 2 3 4 5 6 @interface UIImage ( Additions ) - ( UIImage * ) imageAddingImage : ( UIImage * ) image ; // adds image in the centre - ( UIImage * ) imageAddingImage : ( UIImage * ) image offset : ( CGPoint ) offset ; // add image with custom offset @end

For example, we could create a composite image like this:

// Blue version of the logo UIImage *logo = [UIImage imageNamed:@"logoImageName" tintColor:[UIColor blueColor]]; // Background image in red with corner radius UIImage *backgroundImage = [UIImage imageWithColor:[UIColor redColor] size:CGSizeMake(100,100) cornerRadius:5]; // Composing image UIImage *finalImage = [backgroundImage imageAddingImage:logo]; 1 2 3 4 5 6 7 8 // Blue version of the logo UIImage *logo = [ UIImage imageNamed : @"logoImageName" tintColor : [ UIColor blueColor ] ] ; // Background image in red with corner radius UIImage *backgroundImage = [ UIImage imageWithColor : [ UIColor redColor ] size :CGSizeMake ( 100 , 100 ) cornerRadius : 5 ] ; // Composing image UIImage *finalImage = [ backgroundImage imageAddingImage :logo ] ;

Benefits of dynamic image creation

Less graphic assets Because we are creating on the fly images to customize our UI, we will need less graphic assets, making our application weight lighter and removing work from the graphic designer. Flexibility When we do things programmatically things become flexible. Because we are defining colors and images programmatically, we will be able to change the whole UI appearance by just manipulating a few lines of code. We won’t have to update graphic assets and replace them for new ones anymore. Testing the UI is now easy Because our UI is now flexible, we can test how the UI looks if we change the colour palette. And we can test it as much as we want. Fast development Because we are removing dependencies from our graphic design team, the project development will be faster and more efficient.

Check it out!

In Mobile Jazz we like to use this approach for all above reasons. Our team has developed a UIImage category that helps us to achieve it. You will find it in: GitHub: https://github.com/vilanovi/UIImage-Additions CocoaPods: Pod 'UIImage+Additions', '~>1.0.0' Also, we use to combine it with an extension on UIColor, that adds HEX support and other tools to manipulate colors. GitHub: https://github.com/vilanovi/UIColor-Additions CocoaPods: Pod 'UIColor+Additions', '~>1.0.0'

78EBA888-1918-4C8C-B455-3F3BBC7BD051 Created with sketchtool. Liked it?