如何缩放 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.frame
、button.imageView.bounds
和button.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.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
【讨论】:
这与 [button setBackgroundImage:forState:] 结合使用效果很好。谢谢。 请注意 Jason 所说的内容,您会做得很好。它对 setImage:forState: 不起作用 要让 setImage:forState: 工作,您需要执行以下操作以水平缩放:myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;【参考方案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 inspector 的 Runtime Attributes 中定义特定属性 – imageView.contentModel
,在此您设置相对于枚举 UIViewContentMode
的 rawValue
位置的值。 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 上显示裁剪的图像