开发者

UIImageView: combine UIViewContentModeScaleAspectFit and UIViewContentModeBottom

Is there a way to avoid image stretching in an UIImageView and aligning it to the bottom at the same time? Basically I want to obtain what would happen if it was possible to combine the UIViewContentModeScaleAspectF开发者_如何学Pythonit and UIViewContentModeBottom contentModes.


Found the solution on my own. This code resizes the UIImageView to its image's size, and moves it at the bottom of its superview.

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;


Constraint based approach

You'll want to constrain the left, right, and bottom sides of the UIImageView while ensuring the ratio of the size is the same as the UIImage that it's displaying.

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]];

This will emulate a combination of UIViewContentModeScaleAspectFit and UIViewContentModeBottom but will resize the height of the UIImageView as well.


My solution:

    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;
        }
    }


I have found a much easier way to do it.

imageView.contentMode = .Bottom
imageView.clipToBounds = true

This will prevent the image from resizing no matter what frame it is bounded in. And the clipToBounds part is important because it prevents the non resized image from going outside the imageView bounds.


Late to the party, but a simple solution. On the UIImageView:

  • Use the contentMode property to position the image. (in the current case UIView.ContentMode.bottom)
  • Use the contentScaleFactor property of the UIImageView to scale the image in the content view.

This will maintain the aspect ratio, just calculate the scale you need. For scaleAspectFit:

yourImageView.contentMode = UIView.ContentMode.bottom let relWidthScale = yourImage.size.width/yourImageView.frame.width let relHeightScale = yourImage.size.height/yourImageView.frame.height yourImageView.contentScaleFactor = min(relWidthScale,relHeightScale)

If the UIImageView changes size, you can update the scale by adding an observer to the bounds property of the UIImageView or its container.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜