Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use the aspect fill content mode combined with the top content mode in UIImageView?

Tags:

ios

image

For a UIImageView, I am using the aspect fill content mode. It's OK, but for some images, it will cut from the top because I used clipsToBounds = true. So here is what I want: I want to make the two filters active at the same time, for example:

Here is an image view that I set to aspect fill:

image view with the aspect fill content mode

...and an image view I set using contentMode = .top:

image view with the top content mode

So I want to merge these two content modes. Is it possible? Thanks in advance.

like image 445
V-Dev Avatar asked Dec 19 '17 10:12

V-Dev


People also ask

What is the difference between aspect fill and aspect fit when displaying an image?

The Fit setting will resize an image to fit within the bounds of its container with no cropping. The Fill setting will expand an image to fill the whole container, which may result in some cropping depending on the dimensions of your container and the image you send into it.

How do I change the aspect ratio of a swift image?

👉 In the code, click on the top VStack . In the Attributes inspector, set the Alignment to leading. 👉 Click on the new bottom image in the preview (in the top preview of the news cell, not the bottom preview of the list). 👉 In the Attributes inspector, set the Aspect Ratio to Fill and the Resizing Mode to Stretch .

What is UIImage?

An object that manages image data in your app.

How do I fit an image in Swift?

Swift. You can use the following options to position your image: scaleToFill. scaleAspectFit // contents scaled to fit with fixed aspect.


2 Answers

Update: device scaling is now properly handled, thanks to budidino for that!

You should resize the image, so that it will have the width of your image view, but by keeping its aspect ratio. After that, set the image view's content mode to .top and enable clipping to bounds for it.

The resizeTopAlignedToFill function is a modified version of this answer.

func setImageView() {
    imageView.contentMode = .top
    imageView.clipsToBounds = true

    let image = <custom image>
    imageView.image = image.resizeTopAlignedToFill(newWidth: imageView.frame.width)
}

extension UIImage {
    func resizeTopAlignedToFill(newWidth: CGFloat) -> UIImage? {
        let newHeight = size.height * newWidth / size.width

        let newSize = CGSize(width: newWidth, height: newHeight)

        UIGraphicsBeginImageContextWithOptions(newSize, false, UIScreen.main.scale)
        draw(in: CGRect(origin: .zero, size: newSize))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }
}
like image 151
Tamás Sengel Avatar answered Oct 11 '22 03:10

Tamás Sengel


Try this:

imageView.contentMode = UIViewContentModeTop;
imageView.image = [UIImage imageWithCGImage:image.CGImage scale:image.size.width / imageView.frame.size.width orientation:UIImageOrientationUp];
like image 33
Sergey Fyodorov Avatar answered Oct 11 '22 02:10

Sergey Fyodorov