2012-01-16 16 views
24

Estoy tratando de estirar una imagen de flecha de navegación conservando los bordes para que el medio se estire y los extremos se fijen.Cómo estirar un UIImage conservando las esquinas

Aquí es la imagen que estoy tratando de estirar:

enter image description here

El siguiente código de iOS 5 permite que la imagen se ajuste su tamaño para estirar las partes centrales de la imagen definida por los UIEdgeInsets.

[[UIImage imageNamed:@"arrow.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 7, 15, 15)]; 

Esto resulta en una imagen que se parece a esto (si el marco de la imagen se establece en 70 píxeles de ancho):

enter image description here

Esto es realmente lo que quiero, pero resizableImageWithCapInsets sólo se admite en iOS 5 y posterior.

Antes de iOS 5, el único método similar es stretchableImageWithLeftCapWidth:topCapHeight, pero solo puede especificar las inserciones superior e izquierda, lo que significa que la imagen debe tener bordes con la misma forma.

¿Hay alguna forma de iOS 4 de cambiar el tamaño de la imagen igual que el método resizableImageWithCapInsets de iOS 5 u otra forma de hacerlo?

Respuesta

28

Su suposición aquí es malo:

Antes de iOS 5 el único método similar se stretchableImageWithLeftCapWidth: topCapHeight pero sólo se puede especificar la parte superior e inserciones izquierda lo que significa que la imagen tiene que tener bordes en forma de igualdad.

Las tapas se calculan de la siguiente manera: voy a pasar por la tapa izquierda, pero el mismo principio se aplica a la tapa superior.

Supongamos que su imagen es de 20 píxeles de ancho.

  • Ancho del capuchón izquierdo: es la parte del lado izquierdo de la imagen que no se puede estirar. En el método stretchableImage envía un valor de 10 para esto.
  • Pieza estirable: se supone que tiene un píxel de ancho, por lo que serán los píxeles en la columna "11", a falta de una mejor descripción
  • Esto significa que hay un tope derecho implícito de los 9px restantes de su imagen, esto tampoco se distorsionará.

Esto se toma de los documentation

leftCapWidth

tapas finales especificar la parte de una imagen que no se debe cambiar de tamaño cuando se estira una imagen. Esta técnica se usa para implementar botones y otros elementos de interfaz basados ​​en imágenes de tamaño variable. Cuando se cambia el tamaño de un botón con tapas de extremo, el cambio de tamaño se produce solo en el medio del botón, en la región entre las tapas de los extremos. Las tapas de los extremos mantienen su tamaño y apariencia original.

Esta propiedad especifica el tamaño de la tapa del extremo izquierdo.La porción media (estirable) se supone que tiene 1 píxel de ancho. Por consiguiente, la tapa del extremo derecho se calcula añadiendo el tamaño de la tapa de extremo izquierdo y la parte media juntos y después restando ese valor de la anchura de la imagen:

rightCapWidth = image.size.width - (image.leftCapWidth + 1);

+0

Sí, he eliminado la versión de iOS 5 y ahora estoy usando stretchableImage ya que necesitamos compatibilidad para dispositivos con iOS4. Gracias. – Camsoft

2

Su ejemplo es perfectamente posible utilizar stretchableImageWithLeftCapWidth:topCapHeight: con una tapa izquierda de 15 (al parecer, de leer su código). Eso estirará horizontalmente el botón repitiendo la columna del medio.

3

Puede extender UIImage para permitir estirar una imagen con protección de borde personalizado (que se extiende de este modo el interior de la imagen, en lugar de hacer mosaico):

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 
8
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 
0

Swift versión 3.0 de la respuesta 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) 
Cuestiones relacionadas