¿Cómo escalo un imageView de UIButton?

81

Creé una instancia de UIButton llamada "botón" con una imagen usando [UIButton setImage:forState:]. El button.frame es más grande que el tamaño de la imagen.

Ahora quiero reducir la escala de la imagen de este botón. He intentado cambiar button.imageView.frame, button.imageView.boundsy button.imageView.contentMode, aunque todos parecen ineficaces.

¿Alguien puede ayudarme a escalar UIButtonel imageView de a?

Creé el UIButtonasí:

UIButton *button = [[UIButton alloc] init];
[button setImage:image forState:UIControlStateNormal];

Traté de escalar la imagen de esta manera:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.bounds = CGRectMake(0, 0, 70, 70);

y esto:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.frame = CGRectMake(0, 0, 70, 70);
vcLwei
fuente

Respuestas:

90

Para el póster original, aquí está la solución que encontré:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Esto permitirá que su botón escale horizontalmente. También hay una configuración vertical.

Me tomó varias horas averiguarlo (el nombre de la propiedad es muy poco intuitivo), así que pensé que lo compartiría.

Chris
fuente
buena sugerencia! mi problema fue escalar la imagen estirada para cambiar el tamaño del botón del elemento de barra izquierdo depende de su título.
Valerii Pavlov
1
Esto funciona pero no se dibujará fuera de los límites, piense en ello como alinear el texto en una línea en la que no tendrá nada que pase de los márgenes. Por lo tanto, no obtendrá el efecto como UIViewContentModeScaleAspectFill (con una parte de la imagen recortada) de este.
Hlung
66

Me enfrenté a un problema similar, donde tengo una imagen de fondo (una con borde) y una imagen (bandera) para un botón personalizado. Quería que la bandera se redujera y quedara en el centro. Intenté cambiar el atributo de imageView pero no tuve éxito y estaba viendo esta imagen -

ingrese la descripción de la imagen aquí

Durante mis experimentos, probé:

button.imageEdgeInsets = UIEdgeInsetsMake(kTop,kLeft,kBottom,kRight)

Logré el resultado esperado como:

ingrese la descripción de la imagen aquí

Hitesh Savaliya
fuente
42

Una forma adicional para la configuración en el archivo XIB. Puede elegir esta opción si desea que el texto o la imagen sea Escalar relleno completo en UIButton. Será lo mismo con el código.

UIButton *btn = [UIButton new];

btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
btn.contentVerticalAlignment   = UIControlContentVerticalAlignmentFill;

ingrese la descripción de la imagen aquí

Linh Nguyen
fuente
Si desea estirar la imagen para UIButton es perfecto, entonces puede usar más soporte de activos de imagen y cortar esta imagen. developer.apple.com/library/ios/recipes/…
Linh Nguyen
Ni siquiera estaba al tanto de este método. Rock on
Michael McKenna
23

utilizar

button.contentMode = UIViewContentModeScaleToFill;

no

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Actualizar:

Como comentó @Chris,

Para que esto funcione para setImage: forState :, debe hacer lo siguiente para escalar horizontalmente: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Pavelpanov
fuente
3
Esto funciona muy bien en combinación con [button setBackgroundImage: forState:]. Gracias.
Jason DeFontes
Tenga en cuenta exactamente lo que dijo Jason y estará bien. Que no hace el trabajo para setImage: forState:
dpjanes
7
Para que esto funcione para setImage: forState :, debe hacer lo siguiente para escalar horizontalmente: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
Chris
15
    UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(0,0,70,70)];
    button.buttonType = UIButtonTypeCustom;
    UIImage *buttonImage = [UIImage imageNamed:@"image.png"];

    UIImage *stretchableButtonImage = [buttonImage stretchableImageWithLeftCapWidth:12 topCapHeight:0]; 
    [button setBackgroundImage:stretchableButtonImage forState:UIControlStateNormal]; 
EEE
fuente
@EEE Gracias. Pero hay 2 problemas: 1. Mi pregunta es usar la variable _imageView de UIButton, no la variable _backgroundView. ¿Tengo que hacerlo con backgroundView? 2. la función [UIImage StretchableImageWithLeftCapWidth: topCapHeight:] solo puede hacer que la imagen sea más grande, pero no puede hacer que la imagen sea más pequeña. Gracias de todos modos, y tu respuesta resuelve mi otra pregunta: quiero dibujar un título en el botón con la imagen detrás. Creo que _backgroundImage puede ayudarme. ¿Tiene esta pregunta otra mejor respuesta?
vcLwei
Veo lo que intentas hacer y este es el camino. si su imagen es más grande, cambie su tamaño con una herramienta y todo lo que quiera hacer estará listo. No pierda su tiempo con_imageview. Por cierto, si le gusta esta respuesta, puede votarla y aceptarla
EEE
Puede cambiar el tamaño de su imagen en el programa Vista previa en MacOS. Simplemente abra la imagen y seleccione las herramientas -> Ajustar tamaño
EEE
@EEE Sí, puedo cambiar el tamaño de mi imagen con una herramienta. Pero en mi aplicación a veces también necesito la imagen más grande, no quiero que dos imágenes similares solo difieran en tamaño, eso también desperdicia espacio. Y otra forma de resolver mi pregunta es que puedo usar CGBitmapContext para obtener una imagen más pequeña, pero supongo que esta forma es un inconveniente en comparación con el uso de _imageview. La razón por la que no voté a favor es que mi reputación es menos de 15, de hecho, realmente quiero hacerlo. ¡Gracias!
vcLwei
10

Encontré esta solución.

1) Subclase los siguientes métodos de UIButton

+ (id)buttonWithType:(UIButtonType)buttonType {
    MyButton *toReturn = [super buttonWithType:buttonType];
    toReturn.imageView.contentMode = UIViewContentModeScaleAspectFit;
    return toReturn;
}

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    return contentRect;
}

Y funciona bien.

marcio
fuente
- (CGRect) backgroundRectForBounds: (CGRect) límites, para la imagen de fondo.
Ricky
9

Extraño, el único combo que funcionó para mí (iOS 5.1) es ...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

y

[button setImage:newImage forState:UIControlStateNormal];

Hlung
fuente
Originalmente usé: button.contentMode = UIViewContentModeScaleAspectFit; ahora también necesito escribir button.imageView.contentMode = UIViewContentModeScaleAspectFit; para mantener la relación de aspecto en la retina del iPad 3
Enrico Detoma
7

Simplemente haga (desde el diseño o desde el código):

Desde Diseño

  1. Abra su xib OR Storyboard.
  2. Botón de selección
  3. Dentro Atributo Inspector (lado derecho)> En "Control" sección> seleccionar la última cuarta opción tanto para horizontal y Verical.

[Para el punto n. ° 3: cambie la alineación horizontal y vertical a UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

Desde Código

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
Sandip Patel - SM
fuente
5

así puede resolver su problema:

+ (UIImage*)resizedImage:(UIImage*)image
{
 CGRect frame = CGRectMake(0, 0, 60, 60);
 UIGraphicsBeginImageContext(frame.size);
 [image drawInRect:frame];
 UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();

 return resizedImage;
}
huangkui
fuente
5

De una pequeña prueba que acabo de hacer después de leer aquí, depende de si usa setImage o setBackgroundImage, ambos hicieron el mismo resultado y estiraron la imagen

//for setBackgroundImage
 self.imageButton.contentMode = UIViewContentModeScaleAspectFill;
        [self.imageButton setBackgroundImage:[UIImage imageNamed:@"imgFileName"] forState:UIControlStateNormal];

//for setImage
 self.imageButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
        self.imageButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
    [self.imageButton setImage:[UIImage imageNamed:@"imgFileName"] forState:UIControlStateNormal];
usuario1105951
fuente
muchas
4
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
iomar
fuente
2

Esto también funcionará, ya que backgroundImage se escala automáticamente

[button setBackgroundImage:image forState:UIControlStateNormal];

Harris
fuente
2

Storyboard

Debe definir la propiedad específica de atributos de ejecución de inspector de Identidad - imageView.contentModel, donde se define el valor con relación a rawValuela posición de la enumeración UIViewContentMode. 1 significa scaleAspectFit .

Establecer button.imageView.contentMode en Storyboard

Y la alineación del botón, en el inspector de atributos :

Alineación completa del botón

dimpiax
fuente
1

No puedo obtener una solución para _imageView, pero puedo usar una CGContextRefpara resolverla. Utiliza UIGraphicsGetCurrentContextpara obtener currentContextRef y dibujar una imagen en currentContextRef, y luego escalar o rotar la imagen y crear una nueva imagen. Pero no es perfecto.

el código:

-(UIImage*) scaleAndRotateImage:(UIImage*)photoimage width:(CGFloat)bounds_width height:(CGFloat)bounds_height;
{
    CGImageRef imgRef = photoimage.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);

    bounds.size.width = bounds_width;
    bounds.size.height = bounds_height;

    CGFloat scaleRatio = bounds.size.width / width;
    CGFloat scaleRatioheight = bounds.size.height / height;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = photoimage.imageOrientation;
    switch(orient)
    {
        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid?image?orientation"];
            break;
    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
    {
        CGContextScaleCTM(context, -scaleRatio, scaleRatioheight);
        CGContextTranslateCTM(context, -height, 0);
    }
    else
    {
        CGContextScaleCTM(context, scaleRatio, -scaleRatioheight);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageCopy;
}
vcLwei
fuente
1

Espero que esto pueda ayudar a alguien más:

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill
Dasoga
fuente
-1

Cada UIButton tiene una UIImageView oculta propia. Así que tenemos que configurar el modo de contenido como se indica a continuación ...

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
emraz
fuente
-1

Captura de pantalla en XCode 8

En la parte inferior izquierda de la captura de pantalla, puede ver Propiedades de estiramiento. Intente usar esos.

Duro G.
fuente