Reputation: 1947
I created a UIButton instance named "button" with an image using [UIButton setImage:forState:]
. The button.frame is larger than the image's size.
Now I want to scale this button's image smaller. I tried changing button.imageView.frame
, button.imageView.bounds
and button.imageView.contentMode
, but all seem ineffective.
Can anyone help me scale a UIButton
's imageView?
I created the UIButton
like this:
UIButton *button = [[UIButton alloc] init];
[button setImage:image forState:UIControlStateNormal];
I tried to scale the image like this:
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.bounds = CGRectMake(0, 0, 70, 70);
and this:
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.frame = CGRectMake(0, 0, 70, 70);
Upvotes: 82
Views: 102191
Reputation: 1
Piggy backing off of another answer from 2020, I couldn't get the image to resize with the button. But this solved it :) Go ahead and set these properties in the init() (or wherever) for your button.
self.contentHorizontalAlignment = .fill
self.contentVerticalAlignment = .fill
Top button has those properties as .fill, bottom has default of .center
Upvotes: 0
Reputation: 81
from @JosephH
contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.fill contentVerticalAlignment = UIControl.ContentVerticalAlignment.fill
Upvotes: 2
Reputation: 3229
You can modify imageView by using custom class of UIButton. Please see my answer. https://stackoverflow.com/a/59874762/5693826
Upvotes: 0
Reputation: 5695
I hope this can help to somebody else:
Swift 3+
button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment = UIControlContentVerticalAlignment.fill
Upvotes: 2
Reputation: 12697
You must define specific property in Runtime Attributes of Identity inspector – imageView.contentModel
, where you set value relatively to rawValue
position of enum UIViewContentMode
. 1 means scaleAspectFit.
And button's alignment, in Attributes inspector:
Upvotes: 5
Reputation: 397
At the bottom left of screenshot, you can see Stretching properties. Try using those.
Upvotes: 0
Reputation: 1613
Every UIButton has one hidden UIImageView of its own. So we have to set the content mode like the way given below...
[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
Upvotes: -1
Reputation: 3394
Just do (From Design OR From Code):
[For Point#3: Change Horizontal and vertical Align to UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
Upvotes: 8
Reputation: 8610
This will also work, as the backgroundImage automatically scales
[button setBackgroundImage:image forState:UIControlStateNormal];
Upvotes: 2
Reputation: 2036
An Addition Way for config in XIB file. You can choose this option if you want text or image is Scale full fill in UIButton. It's will be the same with code.
UIButton *btn = [UIButton new];
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
btn.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
Upvotes: 48
Reputation: 275
use
button.contentMode = UIViewContentModeScaleToFill;
not
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
Update:
As @Chris commented,
To get this to work for setImage:forState:, you need to do the following to scale horizontally: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
Upvotes: 25
Reputation: 2287
From small test I just did after reading here, depends if you use setImage or setBackgroundImage, both did the same result and strech the image
//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];
Upvotes: 5
Reputation: 2729
I found this solution.
1) Subclass the following methods of UIButton
+ (id)buttonWithType:(UIButtonType)buttonType {
MyButton *toReturn = [super buttonWithType:buttonType];
toReturn.imageView.contentMode = UIViewContentModeScaleAspectFit;
return toReturn;
}
- (CGRect)imageRectForContentRect:(CGRect)contentRect {
return contentRect;
}
And it works well.
Upvotes: 10
Reputation: 1947
I can't get a solution use by _imageView, but I can use a CGContextRef
to solve it. It use the UIGraphicsGetCurrentContext
to get the currentContextRef and draw a image in currentContextRef, and then scale or rotate the image and create a new image. But it's not perfect.
the code:
-(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;
}
Upvotes: 1
Reputation: 465
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
Upvotes: 4
Reputation: 1346
I'd faced similar problem, where I've a background Image (one with border) and an image (flag) for a custom button. I wanted flag to be scaled down and in center. I tried changing imageView's attribute but didn't succeed and was seeing this image --
During my experiments, I tried :
button.imageEdgeInsets = UIEdgeInsetsMake(kTop,kLeft,kBottom,kRight)
I achieved expected result as :
Upvotes: 68
Reputation: 14348
Strange, the only combo that worked for me (iOS 5.1) is...
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
and
[button setImage:newImage forState:UIControlStateNormal];
Upvotes: 9
Reputation: 3607
For the original poster, here is the solution I found:
commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
This will allow your button to scale horizontally. There is a vertical setting as well.
Took me several hours to figure that one out (the naming of the property is very unintuitive) so figured I'd share.
Upvotes: 95
Reputation: 61
like this can solve your problem:
+ (UIImage*)resizedImage:(UIImage*)image
{
CGRect frame = CGRectMake(0, 0, 60, 60);
UIGraphicsBeginImageContext(frame.size);
[image drawInRect:frame];
UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resizedImage;
}
Upvotes: 5
Reputation: 37505
I just ran into this same problem, and there's a possible answer in this question:
Why does a custom UIButton image does not resize in Interface Builder?
Essentially, use the backgroundimage property instead, which does get scaled.
Upvotes: 8
Reputation: 4536
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];
Upvotes: 15