Using stretchable images in iOS
Stretchable images are used quite often for different customization scenarios. First of all it’s a future-proof solution that will not require replacing assets each time you resize elements in your views. Secondly it’s an application’s size optimization, because you can avoid duplicates for elements with different sizes.
Stretchable images can be used to customize many controls:
UITextField, and so on.
Let’s look into example where stretchable images could be useful:
As you can see, “Big Button” stretches background image in a wrong way. To fix this we need to convert our image into stretchable image. To do that you need to select your image in .xcassets folder in Xcode and check
Editor->Show Slicing in top menu. (You can change it back to
Editor -> Show Overview anytime):
Now, the only thing we need is to set “stretchable” and “non-stretchable” areas of our image. Images can be stretched in three ways:
Only horizontally stretchable image,
Only vertically stretchable image and
Both horizontally and vertically stretchable image.
Such image has 9 regions:
- Top-Left corner: Immutable part, will be placed to top-left corner of result area.
- Top border: Horizontally stretchable part, will be stretched between Top corners.
- Top-Right corner: Immutable part, will be placed to top-right corner of result area.
- Left border: Vertically stretchable part, will be stretched between Left corners.
- Center area: Both directions stretchable part, will fill all the area inside.
- Right border: Vertically stretchable part, will be stretched between Right corners.
- Bottom-Left corner: Immutable part, will be placed to bottom-left corner of result area.
- Bottom border: Horizontally stretchable part, will be stretched between Bottom corners.
To better understand what means
non-stretchable regions, I will provide an example image:
All other area (disabled-like white out area) will be ignored. There is a nice place for optimization, but we’ll talk about it little later in this article.
Because in our example we have an image that should be stretched in both directions - we use
vertical and horizontal slicing:
You can also make image stretchable in code:
UIImage(named: "FancyButton")? .resizableImageWithCapInsets( UIEdgeInsetsMake(4, 4, 4, 4), resizingMode: UIImageResizingMode.Stretch )
UIImage(named: "FancyButton")? .stretchableImageWithLeftCapWidth( 4, topCapHeight: 4 )
Now we have nicely stretchable image and can define any button size:
Now when our image is stretchable we need to think about optimization. Because we do not use most parts of our image, we can simply cut them out:
It will save us some amount of application size:
- x1: original image
431 bytes-> optimized image
- x2: original image
1 kb-> optimized image
- x3: original image
2 kb-> optimized image
In total we save ~3 kb for one single image. It could be quite small comparing to our total application size but with more images - size can increase dramatically and even affect application’s loading time.