iOS -可以拉伸UIImageView而不是UIButton?

时间:2021-07-16 00:23:47

Behold:

见:

//UIImageView* stretchTest = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];
//[self addSubview:stretchTest];


UIButton *stretchTest = [UIButton buttonWithType:UIButtonTypeCustom];
[stretchTest setFrame:CGRectMake(0, 0, 400, 100)];
[stretchTest setBackgroundImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal];
[self addSubview:stretchTest];

stretchTest.contentStretch = CGRectMake(0.5, 0.5, 0, 0);
stretchTest.contentMode = UIViewContentModeScaleToFill;

CGRect frame = stretchTest.frame;
frame.size.height = 300;
stretchTest.frame = frame;

Using the UIImageView (commented out above), the image stretches appropriately - rounded corners maintain the correct radius, because only the center pixel of the image gets stretched.

使用UIImageView(在上面注释),图像适当地拉伸——圆角保持正确的半径,因为只有图像的中心像素被拉伸。

Using the UIButton, the image gets stretched incorrectly. The corner radii are not maintained and it gets ugly.

使用UIButton,图像被不正确地拉伸。转角半径没有得到维护,它变得很难看。

Both UIImageView and UIButton are subclasses of UIView. Why does the button resize differently than the imageView?

UIImageView和UIButton都是UIView的子类。为什么按钮的大小与imageView不同?

2 个解决方案

#1


11  

You're making assumptions about the way UIButton works. It's not implemented the same way as UIImageView. UIImageView is just a view, with no subviews, and its contents is the image. UIButton is different, and the way it works is a private implementation detail.

你在假设UIButton的工作方式。它的实现方式与UIImageView不同。UIImageView只是一个视图,没有子视图,它的内容是图像。UIButton是不同的,它的工作方式是一个私有实现细节。

If you're trying to stretch an image appropriately on a button, you should use -[UIImage stretchableImageWithLeftCapWidth:topCapHeight:] to get a UIImage that knows how it should be stretched. If you want to stretch just the middle pixel, you can use something like

如果你想在按钮上适当地拉伸一个图像,你应该使用-[UIImage stretchableImageWithLeftCapWidth:topCapHeight:]来获得一个UIImage,它知道如何拉伸它。如果你想拉伸中间的像素,你可以用类似的方法

UIImage *image = [UIImage imageNamed:@"image.png"];
image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width/2) topCapHeight:floorf(image.size.height/2)];

#2


1  

A UIButton has two types of images it can display -- a foreground image and a background image. The background image for a button is expected to replace the button's background texture. As such, it will stretch to fill the entire background. The button's foreground image is expected to be an icon that may or may not display alongside text; it will not stretch. It may shrink if the frame is smaller than the image, but it will not stretch.

UIButton有两种可以显示的图像——前景图像和背景图像。一个按钮的背景图像将取代按钮的背景纹理。因此,它会拉伸以填充整个背景。该按钮的前景图像预期是一个图标,可以显示或不能显示在文本旁边;它不会拉伸。如果帧比图像小,它可能会缩小,但不会拉伸。

A button's foreground and background image can be set in code like this:

按钮的前景和背景图像可以用如下代码设置:

// stretchy
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal];  

// not stretchy
[self setImage:forgroundImage forState:UIControlStateNormal]; 

By default, the backgroundImage of a button will use scaleToFill to stretch the image. If you need the image to stretch using cap insets though, you should set them on the image before assigning it to the backgroundImage, like this:

默认情况下,按钮的背景调优将使用scaleToFill来拉伸图像。如果您需要使用cap insets来拉伸图像,您应该在将其分配到backgroundImage之前将其设置为图像,如下所示:

UIImage *image = [UIImage imageNamed:@"bg_image.png"];

/* This assumes your image will have a 1px column and 1px row of pixels 
   in the horizontal and vertical middle of the image that should be
   stretchable. If that's not the case (such as asymetrical buttons) 
   you need to adjust the caps */
image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width/2)
               topCapHeight:floorf(image.size.height/2)];
[self setBackgroundImage:image forState:UIControlStateNormal];  

#1


11  

You're making assumptions about the way UIButton works. It's not implemented the same way as UIImageView. UIImageView is just a view, with no subviews, and its contents is the image. UIButton is different, and the way it works is a private implementation detail.

你在假设UIButton的工作方式。它的实现方式与UIImageView不同。UIImageView只是一个视图,没有子视图,它的内容是图像。UIButton是不同的,它的工作方式是一个私有实现细节。

If you're trying to stretch an image appropriately on a button, you should use -[UIImage stretchableImageWithLeftCapWidth:topCapHeight:] to get a UIImage that knows how it should be stretched. If you want to stretch just the middle pixel, you can use something like

如果你想在按钮上适当地拉伸一个图像,你应该使用-[UIImage stretchableImageWithLeftCapWidth:topCapHeight:]来获得一个UIImage,它知道如何拉伸它。如果你想拉伸中间的像素,你可以用类似的方法

UIImage *image = [UIImage imageNamed:@"image.png"];
image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width/2) topCapHeight:floorf(image.size.height/2)];

#2


1  

A UIButton has two types of images it can display -- a foreground image and a background image. The background image for a button is expected to replace the button's background texture. As such, it will stretch to fill the entire background. The button's foreground image is expected to be an icon that may or may not display alongside text; it will not stretch. It may shrink if the frame is smaller than the image, but it will not stretch.

UIButton有两种可以显示的图像——前景图像和背景图像。一个按钮的背景图像将取代按钮的背景纹理。因此,它会拉伸以填充整个背景。该按钮的前景图像预期是一个图标,可以显示或不能显示在文本旁边;它不会拉伸。如果帧比图像小,它可能会缩小,但不会拉伸。

A button's foreground and background image can be set in code like this:

按钮的前景和背景图像可以用如下代码设置:

// stretchy
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal];  

// not stretchy
[self setImage:forgroundImage forState:UIControlStateNormal]; 

By default, the backgroundImage of a button will use scaleToFill to stretch the image. If you need the image to stretch using cap insets though, you should set them on the image before assigning it to the backgroundImage, like this:

默认情况下,按钮的背景调优将使用scaleToFill来拉伸图像。如果您需要使用cap insets来拉伸图像,您应该在将其分配到backgroundImage之前将其设置为图像,如下所示:

UIImage *image = [UIImage imageNamed:@"bg_image.png"];

/* This assumes your image will have a 1px column and 1px row of pixels 
   in the horizontal and vertical middle of the image that should be
   stretchable. If that's not the case (such as asymetrical buttons) 
   you need to adjust the caps */
image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width/2)
               topCapHeight:floorf(image.size.height/2)];
[self setBackgroundImage:image forState:UIControlStateNormal];