UIImageView: combine UIViewContentModeScaleAspectFit and UIViewContentModeBottom

Is there a way to avoid stretching the image in UIImageViewwhile aligning it to the bottom? Basically, I want to get something that will happen, if it were possible to combine UIViewContentModeScaleAspectFitand UIViewContentModeBottom contentModes.

+3
source share
4 answers

I found a solution myself. This code resizes UIImageViewto its size imageand moves it to the bottom of its supervisor.

CGSize initialImageSize = imageView.size;

CGSize imageSize = imageView.image.size;
CGFloat aspectRatio = imageSize.width / imageSize.height;

CGRect imageFrame = imageView.frame;

if (initialImageSize.width / aspectRatio <= initialImageSize.height) {
    imageFrame.size.width = initialImageSize.width;
    imageFrame.size.height = imageFrame.size.width / aspectRatio;
} else {
    imageFrame.size.height = initialImageSize.height;
    imageFrame.size.width = imageFrame.size.height * aspectRatio;
}

CGRect parentFrame = imageView.superview.frame;
imageFrame.origin.y = (parentFrame.origin.y + parentFrame.size.height) - imageFrame.size.height;

imageView.frame = imageFrame;
+1
source

Constraint Based Approach

You want to limit the sides left, rightand bottom UIImageViewat the same time the aspect ratio will be the same as the displayed one UIImage.

UIImage *image; // allocate image object here
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[parent addSubview:imageView]; // add imageView to proper view with addSubview: here
UIView *superview = imageView.superview; // match width and bottom of self.superview
CGFloat ratio = image.size.width / image.size.height;

NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeLeft multiplier:1.f constant:0.f];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeRight multiplier:1.f constant:0.f];
NSLayoutConstraint *ratioConstraint = [NSLayoutConstraint constraintWithItem:imageView
                                                                    attribute:NSLayoutAttributeWidth
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:imageView
                                                                    attribute:NSLayoutAttributeHeight
                                                                   multiplier:ratio
                                                                     constant:1.f];
[imageView addConstraint:ratioConstraint];
[superview addConstraints:@[leftConstraint, bottomConstraint, rightConstraint]];

UIViewContentModeScaleAspectFit UIViewContentModeBottom, UIImageView.

+1

My decision:

    float newwidth;
    float newheight;

    if (image.size.height>=image.size.width){
        newheight=imageview.frame.size.height;
        newwidth=(image.size.width/image.size.height)*newheight;

        if(newwidth>imageview.frame.size.width){
            float diff=imageview.frame.size.width-newwidth;
            newheight=newheight+diff/newheight*newheight;
            newwidth=imageview.frame.size.width;
        }

    }
    else{
        newwidth=imageview.frame.size.width;
        newheight=(image.size.height/image.size.width)*newwidth;

        if(newheight>imageview.frame.size.height){
            float diff=imageview.frame.size.height-newheight;
            newwidth=newwidth+diff/newwidth*newwidth;
            newheight=imageview.frame.size.height;
        }
    }
0
source

I found a much easier way to do this.

imageView.contentMode = .Bottom
imageView.clipToBounds = true

This will prevent the image from being resized no matter which frame it is limited to. And the clipToBounds part is important because it prevents the image from moving without resizing beyond the borders of the image.

0
source

Source: https://habr.com/ru/post/1792481/


All Articles