I have an s3 link using which I need to load an image in UIImageView. I don't have the dimensions of image with me. I have defined mainImageView (leading and trailing constraints) in storyboard
In the code, I am loading the image using:
mainImageView.setImageWith(URL(string: ("https:" + (content?.imagePath)!)), placeholderImage: nil)
Do we have any way of resizing the container once the image loads? I want the container to take the dimensions (height and width) of the image. I heard that there is something called content wrap in Android to achieve the same. However, I am unable to find an equivalent in iOS.
If you are using Autolayout, you dont actually have to do much as UIImageView has an intrinsic size which makes it take the width and height of the image. In your .xib or .storyboard you need to position the image view so that it can resolve its position(horizontal and vertical). For size you can provide a default image(ow autolayout will show error).
When you will change the image at runtime, the imageview will take the size of its image.
You can achieve it using:
imgView.frame = [self frameForImage:self.image inImageViewAspectFit:imgView];
function implementation:
-(CGRect)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)imageView
{
float imageRatio = image.size.width / image.size.height;
float viewRatio = imageView.frame.size.width / imageView.frame.size.height;
if(imageRatio < viewRatio) {
float scale = imageView.frame.size.height / image.size.height;
float width = scale * image.size.width;
float topLeftX = (imageView.frame.size.width - width) * 0.5;
return CGRectMake(topLeftX, 0, width, imageView.frame.size.height);
} else {
float scale = imageView.frame.size.width / image.size.width;
float height = scale * image.size.height;
float topLeftY = (imageView.frame.size.height - height) * 0.5;
return CGRectMake(0, topLeftY, imageView.frame.size.width, height);
}
}
You can resize the image by modifying its frame to the image's size:
mainImageView.frame = CGRect(origin: mainImageView.frame.origin, size: mainImageView.image.size)
If you are using Auto Layout, you need to modify the height and width constraints accordingly or let the layout to its job.
how can i set the height of UIImageView and leaving other attributes as it is from the .xib? i have UIImageView in .xib file but i only want to set height of it programmatically. can it be done?
Yes It can be done. For eg: If you have UIImageView as imageView then do the below to change the specific frame value.
Way - 1
CGRect rect = imageView.frame;
rect.size.height = /* YOUR_HEIGHT */;
imageView.frame = rect;
Way - 2
imageView.frame = CGRectMake(imageView.frame.origin.x, imageView.frame.origin.y, imageView.frame.size.width, /* YOUR_HEIGHT */);
I highly recommend you to add https://github.com/AlexDenisov/FrameAccessor to your project. It allows to work with frame directly, for example:
view.x = 15.;
view.width = 167.;
I am using the following animation to show a full screen image of a thumbnail onto the view:
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[testImageView setFrame:CGRectMake(0, 0, testImage.size.width, testImage.size.height)];
}completion:^(BOOL finished){
}];
However, this will not contain the image within the bounds of the screen if it is a large image.
Is there a way that I can set the width of the image to the width of the screen, and adjust the image's height then to keep the proper aspect ratio?
Like the above method but with a bit more modification:
CGFloat verticalScale = image.height / bounds.height;
CGFloat horizontalScale = image.width / bounds.width;
CGFloat scale = max(verticalScale,horizontalScale);
CGFloat imageViewHeight = image.height / scale;
CGFloat imageViewWidth = image.width / scale;
CGRect imageViewFrame = CGRectMake(x: DESIRE_X, y: DESIRE_Y, width:imageViewWidth ,height:imageViewHeight)
imageView.frame = imageViewFrame;
imageView.contentMode = UIViewContentModeScaleAspectFill;
CGRect bounds = [UIScreen mainScreen].bounds;
[testImageView setFrame:bounds];
testImageView.contentMode = UIViewContentModeScaleAspectFit;
But there may be some paddings if the image's scale is not equal to screen's.If you prefer the image to cover the full screen, then change contentMode to UIViewContentModeScaleAspectFill.
Please try this below code:
testImageView
=[[UIImageView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y ,self.view.frame.size.width, self.view.frame.size.height
)]
For Example:
I can get the height of UIImageView(identifier:ImgView) by the top and bottom constraints and I want to let its width be (4/3 x height).
How can I do it?
I have ever tried doing it by this sentence:
ImgView.frame.width = ImgView.frame.height * 4.0 / 3.0
But it didn't work with an error said:
it can't assign to ImgView.frame.width
So, how can I achieve this?
Use a ratio constraint. Easy peasy.
Try this:
CGRect frame = ImgView.frame;
frame.size.width = frame.size.height * 4/3;
ImgView.frame = frame;
Or a one-liner:
ImgView.frame = CGRectMake(ImgView.frame.origin.x,
ImgView.frame.origin.y,
ImgView.frame.size.height * 4/3,
ImgView.frame.size.height);
I want to add an image to a UIButton, and also want to scale my image to fit with the UIButton (make image smaller). Please show me how to do it.
This is what I have tried, but it does't work:
Adding image to button and using setContentMode:
[self.itemImageButton setImage:stretchImage forState:UIControlStateNormal];
[self.itemImageButton setContentMode:UIViewContentModeScaleAspectFit];
Making a "stretch image":
UIImage *stretchImage = [updatedItem.thumbnail stretchableImageWithLeftCapWidth:0 topCapHeight:0];
I had the same problem. Just set the ContentMode of the ImageView that is inside the UIButton.
[[self.itemImageButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[self.itemImageButton setImage:[UIImage imageNamed:stretchImage] forState:UIControlStateNormal];
None of the answers here really worked for me, I solved the problem with the following code:
button.contentMode = UIViewContentModeScaleToFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
You can do this in the Interface Builder as well.
The easiest way to programmatically set a UIButton imageView in aspect fit mode :
Swift
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit
Objective-C
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
Note:
You can change .scaleAspectFit (UIViewContentModeScaleAspectFit) to .scaleAspectFill (UIViewContentModeScaleAspectFill) to set an aspect fill mode
If you really want to scale an image, do it, but you should resize it before using it. Resizing it at run time will just lose CPU cycles.
This is the category I'm using to scale an image :
UIImage+Extra.h
#interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
#end;
UIImage+Extra.m
#implementation UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (!CGSizeEqualToSize(imageSize, targetSize)) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(#"could not scale image");
return newImage ;
}
#end
You can use it to the size you want. Like :
[self.itemImageButton setImage:[stretchImage imageByScalingProportionallyToSize:CGSizeMake(20,20)]];
I had problems with the image not resizing proportionately so the way I fixed it was using edge insets.
fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
This can now be done through IB's UIButton properties. The key is to set your image as a the background, otherwise it won't work.
Expanding on Dave's answer, you can set the contentMode of the button's imageView all in IB, without any code, using Runtime Attributes:
1 means UIViewContentModeScaleAspectFit,
2 would mean
UIViewContentModeScaleAspectFill.
1 - clear Button default text (important)
2 - set alignment like image
3 - set content mode like image
If you simply want to reduce your button image:
yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
I have a method that does it for me.
The method takes UIButton and makes the image aspect fit.
-(void)makeImageAspectFitForButton:(UIButton*)button{
button.imageView.contentMode=UIViewContentModeScaleAspectFit;
button.contentHorizontalAlignment=UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment=UIControlContentVerticalAlignmentFill;
}
The cleanest solution is to use Auto Layout. I lowered Content Compression Resistance Priority of my UIButton and set the image (not Background Image) via Interface Builder. After that I added a couple of constraints that define size of my button (quite complex in my case) and it worked like a charm.
Swift 5.0
myButton2.contentMode = .scaleAspectFit
myButton2.contentHorizontalAlignment = .fill
myButton2.contentVerticalAlignment = .fill
make sure that you have set the image to Image property, but not to the Background
Background image can actually be set to scale aspect fill pretty easily. Just need to do something like this in a subclass of UIButton:
- (CGRect)backgroundRectForBounds:(CGRect)bounds
{
// you'll need the original size of the image, you
// can save it from setBackgroundImage:forControlState
return CGRectFitToFillRect(__original_image_frame_size__, bounds);
}
// Utility function, can be saved elsewhere
CGRect CGRectFitToFillRect( CGRect inRect, CGRect maxRect )
{
CGFloat origRes = inRect.size.width / inRect.size.height;
CGFloat newRes = maxRect.size.width / maxRect.size.height;
CGRect retRect = maxRect;
if (newRes < origRes)
{
retRect.size.width = inRect.size.width * maxRect.size.height / inRect.size.height;
retRect.origin.x = roundf((maxRect.size.width - retRect.size.width) / 2);
}
else
{
retRect.size.height = inRect.size.height * maxRect.size.width / inRect.size.width;
retRect.origin.y = roundf((maxRect.size.height - retRect.size.height) / 2);
}
return retRect;
}
in xCode 13.4.1, configure style to default and state config to default
For Xamarin.iOS (C#):
myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
You just need to set content mode of UIButton imageview for three events. -
[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateHighlighted];
[cell.imgIcon setImage:[UIImage imageWithData:data] forState:UIControlStateSelected];
We have code for three event bcoz while highlighting or selecting if button size is SQUARE and image size is rectangle then it will show square image at the time of highlighting or selecting.
I am sure it will work for you.