Using stretchable images in Xcode storyboards Using stretchable images in Xcode storyboards ios ios

Using stretchable images in Xcode storyboards


Update for iOS 7+
iOS 7+ now supports stretchable images natively via the asset catalog. Using the asset catalog you can now specify how images are sliced and how they scale (stretch or tile). These asset catalog attributes for the image will be reflected immediately in storyboard. Great new improvement. For more info, see Apple's docs on the Asset Catalog

For deploying to iOS versions before 7:
It's a little known fact, but you can absolutely set cap insets of an image using only Interface Builder/Storyboard and the stretching properties in the attributes inspector. Thanks to Victor for the original answer.

Looking at the stretching properties in the attributes inspector of a UIImage, the X and Y values are the positions for the stretch starting point, relative to the entire width and height of the image. A value of 0.5 would mean a point in the middle of the image.

The width and height are sizes for the stretchable area relative to the image size. So, setting the width to a value of 1 / imageWidth would set the stretchable area to be 1px wide.

Most stretchable images will stretch from the middle, so using these values for X,Y, Width, & Height will usually work:

X = 0.5Y = 0.5Width = 1/imageWidthHeight = 1/imageHeight

Note: Unless you have a very small image you are stretching, this means that width and height properties will be very small (e.g. 0.008) and 0.0 can be used instead. So, practically speaking, 0.5, 0.5, 0.0, 0.0 will almost always work for X,Y, Width & Height.

In the small number of cases that 0.0 does not work for Width and Height this does mean you need to use a calculator to set these values in IB. However, I think that is generally preferable than having to set it programmatically as you will be able to see the resulting stretched image in IB (WYSIWYG).

Stretchable image attributes

Update: Some people have pointed out that although stretching images works in Storyboard using the above suggestions, stretching images on buttons is still broken, even as of iOS7. Not to worry, this is easily addressed by creating a UIButton category that takes care of setting the cap insets for control states:

@implementation UIButton (Stretchable)/* Automatically set cap insets for the background image. This assumes that   the image is a standard slice size with a 1 px stretchable interior */- (void)setBackgroundImageStretchableForState:(UIControlState)controlState{    UIImage *image = [self backgroundImageForState:controlState];    if (image)    {       CGFloat capWidth =  floorf(image.size.width / 2);       CGFloat capHeight =  floorf(image.size.height / 2);       UIImage *capImage = [image resizableImageWithCapInsets:                     UIEdgeInsetsMake(capHeight, capWidth, capHeight, capWidth)];       [self setBackgroundImage:capImage forState:controlState];    }}

Using this category, you can set your stretchable image for your button via Storyboard and then easily ensure that it stretches properly by calling -setBackgroundImageStretchableForState: in your -viewDidLoad. Iterating through your view hierarchy makes it trivial to do this even for a large number of buttons in your view:

NSPredicate *predicate =     [NSPredicate predicateWithFormat:@"self isKindOfClass:%@",[UIButton class]];NSArray *buttons = [self.view.subviews filteredArrayUsingPredicate:predicate];for (UIButton *button in buttons)   [button setBackgroundImageStretchableForState:UIControlStateNormal];

While this isn't quite as good as having a UIButton subclass which does this automatically for you (subclassing UIButton isn't practical since it's a class cluster), it does give you nearly the same functionality with just a bit of boilerplate code in your viewDidLoad -- you can set all your button images in Storyboard and still get them to properly stretch.


With Xcode 6 (and iOS7+ target) you can use slicing editor when working with images assets.Toggle slicing mode with Editor -> Show Slicing menu or press Show Slicing button when select specific image with editor (showed below).

Show Slicing button

Then you can select image for specific display scale and drag rules or edit insets values manually.

Rules

After that you can select this image in Interface Builder. For example I use it for UIButton Background Image (IB button's representation could look bad, but it should be OK when running).

My buttons look well (running iOS 7.1 simulator and iOS 8 device).

enter image description here

This Apple doc link could be helpful.


It's doable in XCode's 5.0 Interface Builder with the assets catalog. Create an image asset ( if you don't already have an asset catalog you can create one as follows:

  1. File->New->File->Resources->Asset Catalog
  2. Then Editor->New Image Set
  3. Set the images for each Idiom & Scale
  4. Then hit the Show Slicing button to set the slices as you wish.

Check Apple docs here: Developer Apple: Asset Catalog HelpThen all you have to do is to set the background image of the button as the requested asset.

EDIT: I've forgot to mention that it works as desired only in iOS7