J'essaie d'étirer une image de flèche de navigation tout en préservant les bords afin que les étirements du milieu et les extrémités soient fixes.
Voici l'image que j'essaie d'étirer:
Le code iOS 5 suivant permet à l'image lorsqu'elle est redimensionnée d'étirer les parties centrales de l'image définies par les UIEdgeInsets.
[[UIImage imageNamed:@"arrow.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 7, 15, 15)];
Il en résulte une image qui ressemble à ceci (si le cadre de l'image est défini sur 70 pixels de large):
C'est en fait ce que je veux, mais resizableImageWithCapInsets n'est pris en charge que sur iOS 5 et versions ultérieures.
Avant iOS 5, la seule méthode similaire est stretchableImageWithLeftCapWidth: topCapHeight mais vous ne pouvez spécifier que les encarts supérieur et gauche, ce qui signifie que l'image doit avoir des bords de forme égale.
Existe-t-il une façon iOS 4 de redimensionner l'image de la même manière que la méthode resizableImageWithCapInsets
d'iOS 5, ou une autre façon de procéder?
Votre hypothèse ici est fausse:
Avant iOS 5, la seule méthode similaire est extensibleImageWithLeftCapWidth: topCapHeight mais vous ne pouvez spécifier que les encarts supérieur et gauche , ce qui signifie que l'image doit avoir des bords de forme égale.
Les capuchons sont définis comme suit - je vais parcourir le capuchon gauche, mais le même principe s'applique au capuchon supérieur.
Supposons que votre image mesure 20 pixels de large.
stretchableImage
, vous envoyez une valeur de 10 pour cela.Ceci est tiré de la documentation
leftCapWidth
Les extrémités définissent la partie d'une image qui ne doit pas être redimensionnée lorsqu'une image est étirée. Cette technique est utilisée pour implémenter des boutons et d'autres éléments d'interface basés sur l'image redimensionnables. Lorsqu'un bouton avec des capuchons d'extrémité est redimensionné, le redimensionnement se produit uniquement au milieu du bouton, dans la zone située entre les capuchons d'extrémité. Les embouts eux-mêmes conservent leur taille et leur apparence d'origine.
Cette propriété spécifie la taille de l'embout gauche. La partie centrale (étirable) est supposée avoir une largeur de 1 pixel. Le capuchon d'extrémité droit est donc calculé en ajoutant la taille du capuchon d'extrémité gauche et la partie médiane ensemble, puis en soustrayant cette valeur de la largeur de l'image:
rightCapWidth = image.size.width - (image.leftCapWidth + 1);
UIImage *image = [UIImage imageNamed:@"img_loginButton.png"];
UIEdgeInsets edgeInsets;
edgeInsets.left = 0.0f;
edgeInsets.top = 0.0f;
edgeInsets.right = 5.0f; //Assume 5px will be the constant portion in your image
edgeInsets.bottom = 0.0f;
image = [image resizableImageWithCapInsets:edgeInsets];
//Use this image as your controls image
Votre exemple est parfaitement possible en utilisant stretchableImageWithLeftCapWidth:topCapHeight:
avec un plafond gauche de 15 (apparemment, à la lecture de votre code). Cela va étirer horizontalement le bouton en répétant la colonne du milieu.
Vous pouvez étendre UIImage pour permettre d'étirer une image avec une protection Edge personnalisée (étirant ainsi l'intérieur de l'image, au lieu de la recouvrir):
UIImage + utils.h:
#import <UIKit/UIKit.h>
@interface UIImage(util_extensions)
//extract a portion of an UIImage instance
-(UIImage *) cutout: (CGRect) coords;
//create a stretchable rendition of an UIImage instance, protecting edges as specified in cornerCaps
-(UIImage *) stretchImageWithCapInsets: (UIEdgeInsets) cornerCaps toSize: (CGSize) size;
@end
UIImage + utils.m:
#import "UIImage+utils.h"
@implementation UIImage(util_extensions)
-(UIImage *) cutout: (CGRect) coords {
UIGraphicsBeginImageContext(coords.size);
[self drawAtPoint: CGPointMake(-coords.Origin.x, -coords.Origin.y)];
UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return rslt;
}
-(UIImage *) stretchImageWithCapInsets: (UIEdgeInsets) cornerCaps toSize: (CGSize) size {
UIGraphicsBeginImageContext(size);
[[self cutout: CGRectMake(0,0,cornerCaps.left,cornerCaps.top)] drawAtPoint: CGPointMake(0,0)]; //topleft
[[self cutout: CGRectMake(self.size.width-cornerCaps.right,0,cornerCaps.right,cornerCaps.top)] drawAtPoint: CGPointMake(size.width-cornerCaps.right,0)]; //topright
[[self cutout: CGRectMake(0,self.size.height-cornerCaps.bottom,cornerCaps.left,cornerCaps.bottom)] drawAtPoint: CGPointMake(0,size.height-cornerCaps.bottom)]; //bottomleft
[[self cutout: CGRectMake(self.size.width-cornerCaps.right,self.size.height-cornerCaps.bottom,cornerCaps.right,cornerCaps.bottom)] drawAtPoint: CGPointMake(size.width-cornerCaps.right,size.height-cornerCaps.bottom)]; //bottomright
[[self cutout: CGRectMake(cornerCaps.left,0,self.size.width-cornerCaps.left-cornerCaps.right,cornerCaps.top)]
drawInRect: CGRectMake(cornerCaps.left,0,size.width-cornerCaps.left-cornerCaps.right,cornerCaps.top)]; //top
[[self cutout: CGRectMake(0,cornerCaps.top,cornerCaps.left,self.size.height-cornerCaps.top-cornerCaps.bottom)]
drawInRect: CGRectMake(0,cornerCaps.top,cornerCaps.left,size.height-cornerCaps.top-cornerCaps.bottom)]; //left
[[self cutout: CGRectMake(cornerCaps.left,self.size.height-cornerCaps.bottom,self.size.width-cornerCaps.left-cornerCaps.right,cornerCaps.bottom)]
drawInRect: CGRectMake(cornerCaps.left,size.height-cornerCaps.bottom,size.width-cornerCaps.left-cornerCaps.right,cornerCaps.bottom)]; //bottom
[[self cutout: CGRectMake(self.size.width-cornerCaps.right,cornerCaps.top,cornerCaps.right,self.size.height-cornerCaps.top-cornerCaps.bottom)]
drawInRect: CGRectMake(size.width-cornerCaps.right,cornerCaps.top,cornerCaps.right,size.height-cornerCaps.top-cornerCaps.bottom)]; //right
[[self cutout: CGRectMake(cornerCaps.left,cornerCaps.top,self.size.width-cornerCaps.left-cornerCaps.right,self.size.height-cornerCaps.top-cornerCaps.bottom)]
drawInRect: CGRectMake(cornerCaps.left,cornerCaps.top,size.width-cornerCaps.left-cornerCaps.right,size.height-cornerCaps.top-cornerCaps.bottom)]; //interior
UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return [rslt resizableImageWithCapInsets: cornerCaps];
}
@end
Version Swift 3.0 de la réponse de Vicky.
var imageInset:UIEdgeInsets = UIEdgeInsets()
imageInset.left = 10.0
imageInset.top = 10.0
imageInset.bottom = 10.0
imageInset.right = 10.0
self.myImageView.image = myimage.resizableImage(withCapInsets: imageInset)