Mise à jour pour iOS 7+.
iOS 7+ prend désormais en charge les images extensibles de manière native via le catalogue d'actifs. À l'aide du catalogue d'actifs, vous pouvez désormais spécifier la façon dont les images sont découpées en tranches et leur mise à l'échelle (étirement ou tuile). Ces attributs du catalogue d'actifs pour l'image seront immédiatement reflétés dans le storyboard. Une nouvelle amélioration importante. Pour plus d'informations, voir Documents d'Apple sur l'Asset Catalog
Pour le déploiement sur des versions d'iOS antérieures à 7 :
C'est un fait peu connu, mais vous pouvez tout à fait définir les inserts de cap d'une image en utilisant uniquement Interface Builder/Storyboard et les propriétés d'étirement de l'inspecteur d'attributs. Merci à Victor pour la réponse originale.
Si l'on regarde les propriétés d'étirement dans l'inspecteur des attributs d'un fichier UIImage
les valeurs X et Y sont les positions du point de départ de l'étirement, par rapport à la largeur et à la hauteur totales de l'image. Une valeur de 0,5 correspond à un point situé au milieu de l'image.
La largeur et la hauteur sont les dimensions de la zone extensible par rapport à la taille de l'image. Ainsi, si vous attribuez à la largeur une valeur de 1 / imageWidth, la zone extensible aura une largeur de 1 pixel.
La plupart des images extensibles s'étireront à partir du milieu, donc l'utilisation de ces valeurs pour X, Y, largeur et hauteur fonctionnera généralement :
X = 0.5
Y = 0.5
Width = 1/imageWidth
Height = 1/imageHeight
Remarque : à moins que vous n'ayez une très petite image à étirer, cela signifie que les propriétés de largeur et de hauteur seront très petites (par exemple 0,008) et que 0,0 peut être utilisé à la place. Donc, en pratique, 0,5, 0,5, 0,0, 0,0 fonctionnera presque toujours pour X,Y, largeur et hauteur.
Dans le petit nombre de cas où 0,0 ne fonctionne pas pour la largeur et la hauteur, cela signifie que vous devez utiliser une calculatrice pour définir ces valeurs dans IB. Cependant, je pense que c'est généralement préférable à un réglage par programme, car vous pourrez voir l'image étirée résultante dans IB (WYSIWYG).
Mise à jour : Certaines personnes ont fait remarquer que bien que l'étirement des images fonctionne dans Storyboard en utilisant les suggestions ci-dessus, l'étirement des images sur les boutons est toujours cassé, même à partir de iOS7. Ne vous inquiétez pas, ce problème est facilement résolu en créant une fonction UIButton
qui se charge de définir les inserts des capuchons pour les états de contrôle :
@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];
}
}
En utilisant cette catégorie, vous pouvez définir votre image extensible pour votre bouton via Storyboard et ensuite vous assurer facilement qu'elle s'étire correctement en appelant -setBackgroundImageStretchableForState:
dans votre -viewDidLoad
. L'itération dans la hiérarchie de votre vue rend cette opération triviale, même pour un grand nombre de boutons dans votre vue :
NSPredicate *predicate =
[NSPredicate predicateWithFormat:@"self isKindOfClass:%@",[UIButton class]];
NSArray *buttons = [self.view.subviews filteredArrayUsingPredicate:predicate];
for (UIButton *button in buttons)
[button setBackgroundImageStretchableForState:UIControlStateNormal];
Bien que ce ne soit pas aussi bien que d'avoir une UIButton
qui fait cela automatiquement pour vous (sous-classez UIButton
n'est pas pratique puisqu'il s'agit d'un regroupement de classes), il vous donne presque la même fonctionnalité avec juste un peu de code passe-partout dans votre viewDidLoad -- vous pouvez définir toutes vos images de boutons dans Storyboard et les faire s'étirer correctement.