在 UIButton 中缩放图像到 AspectFit? ?

我想添加一个图像到一个 UIButton,也想缩放我的图像,以适应 UIButton (使图像更小)。请告诉我怎么做。

这是我试过的方法,但没有用:

  • 向按钮添加图像并使用 setContentMode:
[self.itemImageButton setImage:stretchImage forState:UIControlStateNormal];
[self.itemImageButton setContentMode:UIViewContentModeScaleAspectFit];
  • 制作“拉伸图像”:
UIImage *stretchImage = [updatedItem.thumbnail stretchableImageWithLeftCapWidth:0 topCapHeight:0];
125441 次浏览

If you really want to scale an image, do it, but you should resize it before using it. Resizing it at run time will just lose CPU cycles.

This is the category I'm using to scale an image :

UIImage+Extra.h

@interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
@end;

UIImage+Extra.m

@implementation UIImage (Extras)


- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {


UIImage *sourceImage = self;
UIImage *newImage = nil;


CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;


CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;


CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;


CGPoint thumbnailPoint = CGPointMake(0.0,0.0);


if (!CGSizeEqualToSize(imageSize, targetSize)) {


CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;


if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;


scaledWidth  = width * scaleFactor;
scaledHeight = height * scaleFactor;


// center the image


if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}




// this is actually the interesting part:


UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0);


CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width  = scaledWidth;
thumbnailRect.size.height = scaledHeight;


[sourceImage drawInRect:thumbnailRect];


newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


if(newImage == nil) NSLog(@"could not scale image");




return newImage ;
}


@end

You can use it to the size you want. Like :

[self.itemImageButton setImage:[stretchImage imageByScalingProportionallyToSize:CGSizeMake(20,20)]];

I had the same problem. Just set the ContentMode of the ImageView that is inside the UIButton.

[[self.itemImageButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[self.itemImageButton setImage:[UIImage imageNamed:stretchImage] forState:UIControlStateNormal];

Hope this helps.

make sure that you have set the image to Image property, but not to the Background

You just need to set content mode of UIButton imageview for three events. -

[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];


[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateHighlighted];


[cell.imgIcon setImage:[UIImage imageWithData:data] forState:UIControlStateSelected];

We have code for three event bcoz while highlighting or selecting if button size is SQUARE and image size is rectangle then it will show square image at the time of highlighting or selecting.

I am sure it will work for you.

I had problems with the image not resizing proportionately so the way I fixed it was using edge insets.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

Background image can actually be set to scale aspect fill pretty easily. Just need to do something like this in a subclass of UIButton:

- (CGRect)backgroundRectForBounds:(CGRect)bounds
{
// you'll need the original size of the image, you
// can save it from setBackgroundImage:forControlState
return CGRectFitToFillRect(__original_image_frame_size__, bounds);
}


// Utility function, can be saved elsewhere
CGRect CGRectFitToFillRect( CGRect inRect, CGRect maxRect )
{
CGFloat origRes = inRect.size.width / inRect.size.height;
CGFloat newRes = maxRect.size.width / maxRect.size.height;


CGRect retRect = maxRect;


if (newRes < origRes)
{
retRect.size.width = inRect.size.width * maxRect.size.height / inRect.size.height;
retRect.origin.x = roundf((maxRect.size.width - retRect.size.width) / 2);
}
else
{
retRect.size.height = inRect.size.height * maxRect.size.width / inRect.size.width;
retRect.origin.y = roundf((maxRect.size.height - retRect.size.height) / 2);
}


return retRect;
}

If you simply want to reduce your button image:

yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);

This can now be done through IB's UIButton properties. The key is to set your image as a the background, otherwise it won't work.

enter image description here

The cleanest solution is to use Auto Layout. I lowered Content Compression Resistance Priority of my UIButton and set the image (not Background Image) via Interface Builder. After that I added a couple of constraints that define size of my button (quite complex in my case) and it worked like a charm.

None of the answers here really worked for me, I solved the problem with the following code:

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

You can do this in the Interface Builder as well.

enter image description here

The easiest way to programmatically set a UIButton imageView in aspect fit mode :

Swift

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

Objective-C

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Note: You can change .scaleAspectFit (UIViewContentModeScaleAspectFit) to .scaleAspectFill (UIViewContentModeScaleAspectFill) to set an aspect fill mode

I have a method that does it for me. The method takes UIButton and makes the image aspect fit.

-(void)makeImageAspectFitForButton:(UIButton*)button{
button.imageView.contentMode=UIViewContentModeScaleAspectFit;
button.contentHorizontalAlignment=UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment=UIControlContentVerticalAlignmentFill;
}

Expanding on Dave's answer, you can set the contentMode of the button's imageView all in IB, without any code, using Runtime Attributes:

enter image description here

  • 1 means UIViewContentModeScaleAspectFit,
  • 2 would mean UIViewContentModeScaleAspectFill.

For Xamarin.iOS (C#):

    myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;

1 - clear Button default text (important)

2 - set alignment like image

3 - set content mode like image

enter image description here

Swift 5.0

 myButton2.contentMode = .scaleAspectFit
myButton2.contentHorizontalAlignment = .fill
myButton2.contentVerticalAlignment = .fill

in xCode 13.4.1, configure style to default and state config to default enter image description here