IOS – can stretch a UIImageView but not a UIButton

iosuibuttonuiimageviewuiview

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.

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

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

Best Answer

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.

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 *image = [UIImage imageNamed:@"image.png"];
image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width/2) topCapHeight:floorf(image.size.height/2)];
Related Topic