如何缩放 UIButton 的 imageView?

Posted

技术标签:

【中文标题】如何缩放 UIButton 的 imageView?【英文标题】:How do I scale a UIButton's imageView? 【发布时间】:2010-12-29 18:18:45 【问题描述】:

我使用[UIButton setImage:forState:] 创建了一个名为“button”的 UIButton 实例,其中包含一个图像。 button.frame 大于图片尺寸。

现在我想缩小这个按钮的图像。我尝试更改button.imageView.framebutton.imageView.boundsbutton.imageView.contentMode,但似乎都无效。

谁能帮我缩放UIButton的imageView?

我这样创建了UIButton

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

我尝试像这样缩放图像:

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

还有这个:

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

【问题讨论】:

【参考方案1】:
    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 谢谢。但有两个问题: 1. 我的问题是使用 UIButton 的 _imageView 变量,而不是 _backgroundView 变量。我必须用 backgroundView 来做吗? 2.函数[UIImage stretchableImageWithLeftCapWidth:topCapHeight:]只能放大图片,不能缩小图片。还是谢谢你,你的回答解决了我的另一个问题:我想在按钮上画一个标题,后面有图片。我认为 _backgroundImage 可以帮助我。这个问题还有其他更好的答案吗? 我明白你想要做什么,这就是方法。如果您的图像更大,然后使用工具调整它的大小,您想要做的一切都会完成。不要在_imageview 上浪费时间。顺便说一句,如果你喜欢这个答案,你可以投票并接受它 您可以在 MacOS 的预览程序中调整图像大小。只需打开图像和选择工具-->调整大小 @EEE 是的,我可以使用工具调整图像大小。但是在我的应用程序中,有时我也需要更大的图像,我不想两个相似的图像只有大小不同,这太浪费空间了。解决我的问题的另一种方法是我可以使用 CGBitmapContext 来获得更小的图像,但我想这种方式与使用 _imageview 相比不方便。我没有投票的原因是我的声誉不到15,实际上我很想这样做。谢谢!【参考方案2】:

我无法获得 _imageView 使用的解决方案,但我可以使用 CGContextRef 来解决它。它使用UIGraphicsGetCurrentContext获取currentContextRef并在currentContextRef中绘制图像,然后缩放或旋转图像并创建新图像。但这并不完美。

代码:

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

【讨论】:

【参考方案3】:

这样可以解决你的问题:

+ (UIImage*)resizedImage:(UIImage*)image

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

 return resizedImage;

【讨论】:

【参考方案4】:

使用

button.contentMode = UIViewContentModeScaleToFill;

不是

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

更新:

正如@Chris 所说,

要使其适用于 setImage:forState:,您需要执行以下操作以水平缩放:myButton.contentHorizo​​ntalAlignment = UIControlContentHorizo​​ntalAlignmentFill;

【讨论】:

这与 [button setBackgroundImage:forState:] 结合使用效果很好。谢谢。 请注意 Jason 所说的内容,您会做得很好。它对 setImage:forState: 不起作用 要让 setImage:forState: 工作,您需要执行以下操作以水平缩放:myButton.contentHorizo​​ntalAlignment = UIControlContentHorizo​​ntalAlignmentFill;【参考方案5】:

我找到了这个解决方案。

1) 继承UIButton的以下方法

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


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

而且效果很好。

【讨论】:

- (CGRect) backgroundRectForBounds:(CGRect)bounds,用于背景图片。【参考方案6】:

我刚刚遇到了同样的问题,这个问题有一个可能的答案:

Why does a custom UIButton image does not resize in Interface Builder?

基本上,改用 backgroundimage 属性,它会被缩放。

【讨论】:

【参考方案7】:

对于原始海报,这是我找到的解决方案:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

这将允许您的按钮水平缩放。还有一个垂直设置。

我花了好几个小时才弄明白这一点(属性的命名非常不直观)所以我想分享一下。

【讨论】:

好建议!我的问题是缩放拉伸图像以更改 leftbaritem 按钮的大小取决于其标题。 这可行,但不会超出边界,可以将其想象为将文本对齐一行,这样您就不会有任何东西通过边距。所以,你不会从这个得到 UIViewContentModeScaleAspectFill 的效果(图像的某些部分被裁剪)。【参考方案8】:

奇怪,唯一对我有用的组合(ios 5.1)是......

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

[button setImage:newImage forState:UIControlStateNormal];

【讨论】:

原来我用的是:button.contentMode = UIViewContentModeScaleAspectFit;现在我还需要写 button.imageView.contentMode = UIViewContentModeScaleAspectFit;在 iPad 3 视网膜上保持纵横比【参考方案9】:
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;

【讨论】:

【参考方案10】:

我遇到过类似的问题,我有一个背景图像(一个带边框)和一个自定义按钮的图像(标志)。我希望将标志按比例缩小并居中。我尝试更改 imageView 的属性,但没有成功,正在看到这张图片 --

在我的实验中,我尝试了:

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

我达到了预期的结果:

【讨论】:

【参考方案11】:

从我刚读完这里的小测试来看,取决于你是使用 setImage 还是 setBackgroundImage,两者都做了相同的结果并拉伸图像

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

【讨论】:

非常感谢...完美的解决方案适合尺寸小于按钮尺寸的小图像...【参考方案12】:

只需做(来自设计或来自代码):

来自设计

    打开您的 xib 或情节提要。 选择按钮 在 Attribute Inspector 内部(右侧)> 在 “Control” 部分 > 选择最后一个 第 4 个选项 用于水平和垂直。李>

[对于点#3:将水平和垂直对齐更改为UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

来自代码

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

【讨论】:

【参考方案13】:

XIB 文件中配置的一种附加方式。 如果您希望文本或图像在 UIButton 中按比例完全填充,则可以选择此选项。 代码也是一样的。

UIButton *btn = [UIButton new];

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

【讨论】:

如果你想为 UIButton 拉伸图像是完美的,那么你可以使用更多的图像资源支持和切片这个图像。 developer.apple.com/library/ios/recipes/… 甚至不知道这种方法。摇滚【参考方案14】:

这也可以,因为 backgroundImage 会自动缩放

[button setBackgroundImage:image forState:UIControlStateNormal];

【讨论】:

【参考方案15】:

每个 UIButton 都有一个隐藏的 UIImageView。所以我们必须像下面给出的方式设置内容模式......

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

【讨论】:

【参考方案16】:

在屏幕截图的左下方,您可以看到拉伸属性。尝试使用这些。

【讨论】:

【参考方案17】:

故事板

您必须在 Identity inspectorRuntime Attributes 中定义特定属性 – imageView.contentModel,在此您设置相对于枚举 UIViewContentModerawValue 位置的值。 1 表示 scaleAspectFit

以及按钮的对齐方式,在属性检查器中:

【讨论】:

【参考方案18】:

我希望这对其他人有帮助:

Swift 3+

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

【讨论】:

【参考方案19】:

您可以使用 UIButton 的自定义类来修改 imageView。请看我的回答。 https://***.com/a/59874762/5693826

【讨论】:

【参考方案20】:

来自@JosephH

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

【讨论】:

以上是关于如何缩放 UIButton 的 imageView?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止UIButton的imageView占用整个UIButton?

如何识别 UIAutomation 中添加到 UIButton 的子视图(imageviews)?

如何使用 Imageview 实现切换行为,没有 UIButton

如何缩放 + 裁剪图像并在 imageview 上显示裁剪的图像

根据状态更改 UIButton 中 ImageView 的 tint 颜色

如何使用 Swift 以编程方式创建 Hexagon UIButton 或 Clickable ImageView