iOS 5 : UIImage and resizableImageWithCapInsets

I recently began writing a short example to learn more about the iOS 5 Appearance API and customizing UINavigationBar objects. The goal was to add a custom background, title and text to the navbar. Once I had this working, to keep a consist look across my application, I began tweaking the buttons on the navbar using the same Appearance API.

As I got further into the customization of the buttons, I ran into a method within UIImage that was introduced in iOS 5, resizableImageWithCapInsets. I found myself getting side-tracked from the original idea of navbar look and feel, to understanding how cap insets work. This post delves into what I learned.

Cap Insets with UIButton

As the documentation describes, you use resizableImageWithCapInsets to add cap insets to an image, when the image is resized or scaled, cap areas are not affected. The best way to understand this is through an example.

Let’s assume I want all the buttons on my UI to have a similar look, a gradient with a white border. Below is the image used for the examples in this post (the button is shown on a gray backdrop so you can see the white border):

Depending on the context of where the button appears, its size may vary. The code to create a button with the image and the corresponding output follow:

UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(80, 130, 160, 44)];  
[button setTitle:@"Test Button" forState:UIControlStateNormal];
 
// Image with without cap insets
UIImage *buttonImage = [UIImage imageNamed:@"blueButton"];
 
[button addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];        
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[[self view] addSubview:button];

As you can see, the button is stretched in all directions. Let’s change the code to include cap insets, however, before we do that, let’s look at the signature of the cap insets method:

– (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

Looking on step further, UIEdgeInserts is defined as:

typedef struct {
   CGFloat top, left, bottom, right;
} UIEdgeInsets;

UIEdgeInsets is structure that specifies float values for each cap inset: top, left, bottom and right areas of an image. To apply this to the image for the button, here is all we need to do:

// Image with cap insets
UIImage *buttonImage = [[UIImage imageNamed:@"blueButton"]  
   resizableImageWithCapInsets:UIEdgeInsetsMake(0, 16, 0, 16)];

This requests that the left and right 16 pixels of the original image are not scaled or resized when stretching the image to accomodate the button size frame defined above. The end results is as shown below:

Cap Insets with UIBarButtonItem

We can use the same image for a button on a navbar (I’ll show the specifics in the next post on customizing the navbar). Without specifying the cap insets, the button looks as follows:

The code below specifies an image where 12 pixels on the top, left, bottom and right be preserved when stretching/resizing the button:

UIImage *backButton = [[UIImage imageNamed:@"blueButton"]  
   resizableImageWithCapInsets:UIEdgeInsetsMake(12, 12, 12, 12)];

The output nows looks as follows:

Next Post

With that under our belt, in the next post I’ll continue with my original idea of customizing UINavigationBar, including background, title and text, as well as the buttons on the navbar.

  1. Very clear explanation on Cap Insets.
    Looking forward to “customizing UINavigationBar”. Thanks

  2. Thanks for this. I’ve been wondering about edge caps on UIButtons for a while. This clears it up.

  3. It’s very nice tutorial ….
    I’d been wondering about edge caps.But today i got it .
    Thank You!!!!

  4. Really good tutorial! I was looking for something that explained this, great job!! Used in a project right away…

  5. Great Article!
    Thank you for writing this up, very clear explanation.

  6. Hey, really good tutorial. works great.. Have a doubt though in UIEdgeInsetsMake(12, 12, 12, 12)

    I would like to ask why is that you have taken 12 as a reference, can it be calculated based on the text size?

  7. Very descriptive and informative. Thumbs up bro :))

  8. Thank you for this post. I was looking for something like this for around an hour. You made my day!

Comments are closed.