How do I scale a UIButton's imageView?

IosUibuttonScale

Ios Problem Overview


I created a UIButton instance named "button" with an image using [UIButton setImage:forState:]. The button.frame is larger than the image's size.

Now I want to scale this button's image smaller. I tried changing button.imageView.frame, button.imageView.bounds and button.imageView.contentMode, but all seem ineffective.

Can anyone help me scale a UIButton's imageView?

I created the UIButton like this:

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

I tried to scale the image like this:

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

and this:

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

Ios Solutions


Solution 1 - Ios

For the original poster, here is the solution I found:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

This will allow your button to scale horizontally. There is a vertical setting as well.

Took me several hours to figure that one out (the naming of the property is very unintuitive) so figured I'd share.

Solution 2 - Ios

I'd faced similar problem, where I've a background Image (one with border) and an image (flag) for a custom button. I wanted flag to be scaled down and in center. I tried changing imageView's attribute but didn't succeed and was seeing this image --

enter image description here

During my experiments, I tried :

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

I achieved expected result as :

enter image description here

Solution 3 - Ios

An Addition Way for config in XIB file. You can choose this option if you want text or image is Scale full fill in UIButton. It's will be the same with code.

UIButton *btn = [UIButton new];

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

enter image description here

Solution 4 - Ios

use

button.contentMode = UIViewContentModeScaleToFill;

not

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Update:

As @Chris commented, >To get this to work for setImage:forState:, you need to do the following to scale horizontally: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Solution 5 - Ios

    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]; 
    



Solution 6 - Ios

I found this solution.

  1. Subclass the following methods of UIButton

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

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

And it works well.

Solution 7 - Ios

Strange, the only combo that worked for me (iOS 5.1) is...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

and

[button setImage:newImage forState:UIControlStateNormal];

Solution 8 - Ios

I just ran into this same problem, and there's a possible answer in this question:

https://stackoverflow.com/questions/1063019/why-does-a-custom-uibutton-image-does-not-resize-in-interface-builder

Essentially, use the backgroundimage property instead, which does get scaled.

Solution 9 - Ios

Just do (From Design OR From Code):

From Design
  1. Open your xib OR Storyboard.
  2. Select button
  3. Inside Attribute Inspector (Right side) > In "Control" section > select last 4th option for both Horizontal and Verical.

[For Point#3: Change Horizontal and vertical Align to UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

From Code
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;

Solution 10 - Ios

like this can solve your problem:

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

Solution 11 - Ios

From small test I just did after reading here, depends if you use setImage or setBackgroundImage, both did the same result and strech the image

//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];

Solution 12 - Ios

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;

Solution 13 - Ios

Storyboard

You must define specific property in Runtime Attributes of Identity inspectorimageView.contentModel, where you set value relatively to rawValue position of enum UIViewContentMode. 1 means scaleAspectFit.

Set button.imageView.contentMode in Storyboard

And button's alignment, in Attributes inspector:

Full alignment of button

Solution 14 - Ios

This will also work, as the backgroundImage automatically scales

[button setBackgroundImage:image forState:UIControlStateNormal];

Solution 15 - Ios

I hope this can help to somebody else:

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill

Solution 16 - Ios

from @JosephH

contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.fill contentVerticalAlignment = UIControl.ContentVerticalAlignment.fill

Solution 17 - Ios

I can't get a solution use by _imageView, but I can use a CGContextRef to solve it. It use the UIGraphicsGetCurrentContext to get the currentContextRef and draw a image in currentContextRef, and then scale or rotate the image and create a new image. But it's not perfect.

the code:

-(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;
}

Solution 18 - Ios

Screenshot in XCode 8

At the bottom left of screenshot, you can see Stretching properties. Try using those.

Solution 19 - Ios

You can modify imageView by using custom class of UIButton. Please see my answer. https://stackoverflow.com/a/59874762/5693826

Solution 20 - Ios

Every UIButton has one hidden UIImageView of its own. So we have to set the content mode like the way given below...

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvcLweiView Question on Stackoverflow
Solution 1 - IosChrisView Answer on Stackoverflow
Solution 2 - IosHitesh SavaliyaView Answer on Stackoverflow
Solution 3 - IosLinh NguyenView Answer on Stackoverflow
Solution 4 - IospavelpanovView Answer on Stackoverflow
Solution 5 - IosEEEView Answer on Stackoverflow
Solution 6 - IosmarcioView Answer on Stackoverflow
Solution 7 - IosHlungView Answer on Stackoverflow
Solution 8 - IosJosephHView Answer on Stackoverflow
Solution 9 - IosSandip Patel - SMView Answer on Stackoverflow
Solution 10 - IoshuangkuiView Answer on Stackoverflow
Solution 11 - Iosuser1105951View Answer on Stackoverflow
Solution 12 - IosiomarView Answer on Stackoverflow
Solution 13 - IosdimpiaxView Answer on Stackoverflow
Solution 14 - IosElijahView Answer on Stackoverflow
Solution 15 - IosDasogaView Answer on Stackoverflow
Solution 16 - IosMichael ColonnaView Answer on Stackoverflow
Solution 17 - IosvcLweiView Answer on Stackoverflow
Solution 18 - IoshaxgadView Answer on Stackoverflow
Solution 19 - IosZAFAR007View Answer on Stackoverflow
Solution 20 - IosemrazView Answer on Stackoverflow