Swift UIImageView Stretched Aspect

2020-05-31 22:59发布

UIImageView renders the size of an image incorrectly. Using Scale Aspect Fit, if the UIImageView is a square the image is the correct aspect ratio with transparency in the areas the image does not fill.

//Image is Square & Correct Size
var imageView = UIImageView(frame: CGRectMake(0, 50, 320, 320))
imageView.clipsToBounds = true
imageView.contentMode = UIViewContentMode.ScaleAspectFit

//Image is Rectangle & Incorrect Size
var imageView = UIImageView(frame: CGRectMake(0, 50, 320, 450))
imageView.clipsToBounds = true
imageView.contentMode = UIViewContentMode.ScaleAspectFit

The UIImageView needs to touch the edges and have transparent space at the top and bottom of the screen and the image inside needs to keep its original ratio rather than stretching taller. I have attached two images of how the image inside the UIImageView is rendering.

ImageView with correct Aspect ImageView with wrong Aspect

6条回答
▲ chillily
2楼-- · 2020-05-31 23:05

I was having the same issue, and what fixed it for me was making sure to set the imageView image after the content mode was set. ie:

    self.imageView.contentMode = UIViewContentMode.ScaleAspectFit
    self.imageView.image = imageChosen

Cheers

查看更多
\"骚年 ilove
3楼-- · 2020-05-31 23:07

Swift 3 version of your code:

imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleBottomMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleTopMargin]
imageView.contentMode = .scaleAspectFit // OR .scaleAspectFill
imageView.clipsToBounds = true
查看更多
我欲成王,谁敢阻挡
4楼-- · 2020-05-31 23:13

There is a great solution here: by olearyj234 .
and it helped me a lot. I suggest taking a look. Also, here is his code in swift 4 and Xcode 9.2:

    class ScaledHeightImageView: UIImageView {

    override var intrinsicContentSize: CGSize {

        if let myImage = self.image {
            let myImageWidth = myImage.size.width
            let myImageHeight = myImage.size.height
            let myViewWidth = self.frame.size.width

            let ratio = myViewWidth/myImageWidth
            let scaledHeight = myImageHeight * ratio

            return CGSize(width: myViewWidth, height: scaledHeight)
        }

        return CGSize(width: -1.0, height: -1.0)
    }

}
查看更多
够拽才男人
5楼-- · 2020-05-31 23:20

That's the intended behaviour for UIViewContentMode.ScaleAspectFit. From the docs:

UIViewContentModeScaleAspectFit

The option to scale the content to fit the size of the view by maintaining the aspect ratio. Any remaining area of the view’s bounds is transparent.

It seems from what you describe that you need UIViewContentMode.ScaleAspectFill

UIViewContentModeScaleAspectFill

The option to scale the content to fill the size of the view. Some portion of the content may be clipped to fill the view’s bounds.

查看更多
Viruses.
6楼-- · 2020-05-31 23:21

Swift 5

You can apply UIView.ContentMode.scaleAspectFit only for UIImageView like this:

        let logoImage:UIImage = UIImage(named: "my_logo")!

        let logoImageView = UIImageView(image: logoImage)

        logoImageView.contentMode = UIView.ContentMode.scaleAspectFit

        return logoImageView
查看更多
仙女界的扛把子
7楼-- · 2020-05-31 23:29

I added an autoresizing mask to the UIImageView and it now displays the correct ratios.

imageView.autoresizingMask = UIViewAutoresizing.FlexibleBottomMargin | UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleRightMargin | UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleTopMargin | UIViewAutoresizing.FlexibleWidth
imageView.contentMode = UIViewContentMode.ScaleAspectFit

This answer helped me: Captured photo is stretched with AVCaptureSession sessionPreset = AVCaptureSessionPresetPhoto as I was using an image that was taken through the phones camera.

查看更多
登录 后发表回答