I have a UIImageView
generated in source (programmatically). That UIImageView
needs to have a max size, for both width and height. In this view, I load a image from URL and set after the download ends. I don't know previously, what is the size of the image, but I need to keep the aspect ratio and make the UIImageView
with a size that maintains that aspect.
If the image is smaller, in one or both dimension, I want the UIImageView
has the size necessary to maintain the aspect ratio without stretch the image.
I'll give two examples considering the max size for UIImageView
with 250 X 350
.
Example 1:
The image size is 800 X 800
.
The size of UIImageView
needs to be 250 X 250
.
Example 2:
The image size is 200 X 250
.
The size of UIImageView
needs to be 200 X 250
.
How can I do this with auto-layout.
You'll need three constraints here. One that maintains the aspect ratio, one that makes sure the width is no larger than the maximum, and one that makes sure the height is no larger than the maximum. As of August 2016, Interface Builder does not support constraints referencing other constraints, so – at a minimum – the aspect ratio constraint must be done in code.
The aspect ratio is the only one that takes any thinking. Let V_w and V_h be the width and height, respectively, of your image view. Let I_w and I_h be the width and height, respectively, of your image. Then, to maintain the image's aspect ratio, the following equation must remain true:
Or, equivalently:
Ok, looking good. Let's write some code. In this code, I assume you have MAX_HEIGHT
and MAX_WIDTH
defined earlier. Note that this code must target iOS 9.0 or later. If you're targeting an earlier version of iOS, see the block below.
// Constrain the desired aspect ratio
[imageView.widthAnchor constraintEqualToAnchor:imageView.heightAnchor
multiplier:aspectRatioMult].active = YES;
// Constrain height
[imageView.heightAnchor constraintLessThanOrEqualToConstant:MAX_HEIGHT].active = YES;
// Constrain width
[imageView.widthAnchor constraintLessThanOrEqualToConstant:MAX_WIDTH].active = YES;
For code targeting iOS versions before 9.0, NSLayoutAnchor
is not available. Instead, you'll have to make due with NSLayoutConstraint
.
CGFloat aspectRatioMult = (imageView.image.size.width / imageView.image.size.height);
// Constrain the desired aspect ratio
[imageView addConstraint:
[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:imageView
attribute:NSLayoutAttributeHeight
multiplier:aspectRatioMult
constant:0]];
// Constrain height
[imageView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageView(<=max)]"
options:0
metrics:@{@"max" : @(MAX_HEIGHT)}
views:@{@"imageView" : imageView}]];
// Constrain width
[imageView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:[imageView(<=max)]"
options:0
metrics:@{@"max" : @(MAX_WIDTH)}
views:@{@"imageView" : imageView}]];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With