I solved this by subclassing the UIImageView and overriding the setImage: method. The subclass will first save the original values ββfor the start and size so that it can use the original size of the set as a bounding box.
I set the content mode to UIViewContentModeAspectFit. Inside setImage: I grabbed the ratio of image width to height, and then resized the image to fit the same ratio as the image. After resizing, I adjusted the frame properties to set the image in the same place as before, and then I called super setImage :.
This leads to the presentation of the image, the frame of which is adjusted to exactly match the image, so the aspect is suitable and the properties of the image frame make heavy lifting when placing the image where it should be in order to get the same effect.
Here is the code I used:
First of all, and I believe that this is quite useful in general, this is a category in UIView that simplifies setting frame properties when viewing using properties such as left, right, top, bottom, width, height, etc.
UIImageView + FrameAdditions
@interface UIView (FrameAdditions) @property CGFloat left, right, top, bottom, width, height; @property CGPoint origin; @end @implementation UIView (FrameAdditions) - (CGFloat)left { return self.frame.origin.x; } - (void)setLeft:(CGFloat)left { self.frame = CGRectMake(left, self.frame.origin.y, self.frame.size.width, self.frame.size.height); } - (CGFloat)right { return self.frame.origin.x + self.frame.size.width; } - (void)setRight:(CGFloat)right { self.frame = CGRectMake(right - self.frame.size.width, self.frame.origin.y, self.frame.size.width, self.frame.size.height); } - (CGFloat)top { return self.frame.origin.y; } - (void)setTop:(CGFloat)top { self.frame = CGRectMake(self.frame.origin.x, top, self.frame.size.width, self.frame.size.height); } - (CGFloat)bottom { return self.frame.origin.y + self.frame.size.height; } - (void)setBottom:(CGFloat)bottom { self.frame = CGRectMake(self.frame.origin.x, bottom - self.frame.size.height, self.frame.size.width, self.frame.size.height); } - (CGFloat)width { return self.frame.size.width; } - (void)setWidth:(CGFloat)width { self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, width, self.frame.size.height); } - (CGFloat)height { return self.frame.size.height; } - (void)setHeight:(CGFloat)height { self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, height); } - (CGPoint)origin { return self.frame.origin; } - (void)setOrigin:(CGPoint)origin { self.frame = CGRectMake(origin.x, origin.y, self.frame.size.width, self.frame.size.height); } @end
This is a subclass of UIImageView. It is not fully tested, but should get this idea. This can be expanded to customize your own new alignment modes.
BottomCenteredImageView
@interface BottomCenteredImageView : UIImageView @end @interface BottomCenteredImageView() { CGFloat originalLeft; CGFloat originalBottom; CGFloat originalHeight; CGFloat originalWidth; } @end @implementation BottomCenteredImageView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if(self) { [self initialize]; } return self; } - (void)awakeFromNib { [self initialize]; } - (void)initialize { originalLeft = self.frame.origin.x; originalHeight = CGRectGetHeight(self.frame); originalWidth = CGRectGetWidth(self.frame); originalBottom = self.frame.origin.y + originalHeight; } - (void)setImage:(UIImage *)image { if(image) { self.width = originalWidth; self.height = originalHeight; self.left = originalLeft; self.bottom = originalBottom; float myWidthToHeightRatio = originalWidth/originalHeight; float imageWidthToHeightRatio = image.size.width/image.size.height; if(myWidthToHeightRatio >= imageWidthToHeightRatio) { // Calculate my new width CGFloat newWidth = self.height * imageWidthToHeightRatio; self.width = newWidth; self.left = originalLeft + (originalWidth - self.width)/2; self.bottom = originalBottom; } else { // Calculate my new height CGFloat newHeight = self.width / imageWidthToHeightRatio; self.height = newHeight; self.bottom = originalBottom; } self.contentMode = UIViewContentModeScaleAspectFit; [super setImage:image]; } else { [super setImage:image]; } } @end