adri567
adri567

Reputation: 661

scale image to size with aspectFit

I am building a app where you can drag images inside a view. Currently it look like this:

enter image description here

enter image description here

As you can see I marked the background color from the image view in green. The image view has contentMode aspectFit and it is 40 pixels smaller than the black view behind it. I want the that the image is the full length and width of the image view. The contentMode should be aspectFit, that nothing is cut away from the image. Is it possible to resize the image, that it has 20 pixels or a bit more space from the view?

Upvotes: 1

Views: 1726

Answers (4)

DonMag
DonMag

Reputation: 77462

One approach...

  • embed a UIImageView in a (green) UIView
  • constrain the imageView on all 4 sides + 20-pts "padding"
  • constrain the width of the greenView (or its leading and trailing)
  • constrain the Y position of the greenView (top or centerY)
  • constrain the height of the imageView with a multiplier based on the image width and height

Here is a simple example:

class ViewController: UIViewController {

    let imgView: UIImageView = {
        let v = UIImageView()
        v.contentMode = .scaleToFill
        return v
    }()

    let greenView: UIView = {
        let v = UIView()
        v.backgroundColor = .green
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        // replace with your image name
        guard let img = UIImage(named: "bkg640x360") else {
            fatalError("Could not load image!")
        }

        view.backgroundColor = .black

        // set the imgView's image
        imgView.image = img

        // use auto-layout constraints
        imgView.translatesAutoresizingMaskIntoConstraints = false
        greenView.translatesAutoresizingMaskIntoConstraints = false

        // add imgView to greenview
        greenView.addSubview(imgView)

        // add greenView to self.view
        view.addSubview(greenView)

        // we want to respect safe-area
        let g = view.safeAreaLayoutGuide

        NSLayoutConstraint.activate([

            // constrain greenView leading and trailing to view (safeArea)
            greenView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
            greenView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),

            // constrain greenView centerY to view centerY
            greenView.centerYAnchor.constraint(equalTo: g.centerYAnchor, constant: 0.0),

            // constrain imgView to all 4 sides of greenView with 20-pts "padding"
            imgView.topAnchor.constraint(equalTo: greenView.topAnchor, constant: 20.0),
            imgView.bottomAnchor.constraint(equalTo: greenView.bottomAnchor, constant: -20.0),
            imgView.leadingAnchor.constraint(equalTo: greenView.leadingAnchor, constant: 20.0),
            imgView.trailingAnchor.constraint(equalTo: greenView.trailingAnchor, constant: -20.0),

            // constrain imgView proportional height equal to image height / width
            imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: img.size.height / img.size.width),

        ])

    }

}

The result, using a 640 x 360 image:

enter image description here

and using a 512 x 512 (square) image:

enter image description here

These are my source images:

enter image description here

enter image description here

Upvotes: 1

Ataberk Canıtez
Ataberk Canıtez

Reputation: 11

Simple math can solve this.

for shortcuts: H -> height , W -> Width

We know that general formula for this is: h1 / w1 = h2 / w2

Hscreen / Wscreen = Himage / Wimage

so we know screen width, image height and image width.

we can get screen width as -> view.frame.width

also we can get image size as -> image.size.width and image.size.height

Hscreen = (Himage) * (WScreen) / Wimage

..

you can use Hscreen to imageViews height anchor.

Upvotes: 1

Toto
Toto

Reputation: 613

If you want to keep the image at the same size, but don't want to stretched it. your solution is something else.

  1. Display your image as .aspectFit as in the question

  2. the green view that you display replace it with the same image in .aspectFill but blur it as much as it looks good.

Upvotes: 1

Ram
Ram

Reputation: 804

@adri567 You should use UIViewContentModeScaleToFill property like

imageView.contentMode = .scaleToFill

Try with this!

Upvotes: 2

Related Questions