Code Tree
Code Tree

Reputation: 2209

Resize an UIImageView to fit in screen

There is a UIImageView passed as an property through a segue from another view controller where the user has scribbled on an image. I couldn't fit / scale the image to fit in a UIView in the receiving view controller. No matter what I try it goes over the screen.

Here are some I tried with zero success in viewDidLoad()

incomingImgView?.frame = CGRect(x: 0, y: 0, width: view.bounds.width  , height:  view.bounds.height)
// incomingImgView?.frame = CGRect(x: 0, y: 0, width: 100  , height: 100)

incomingImgView?.contentMode = .scaleAspectFit

incomingImgView?.clipsToBounds = true

//incomingImgView?.frame = view.bounds
viewContainer.addSubview(incomingImgView!)


// incomingImgView?.image?.scaleImage(toSize: CGSize(width: 100, height: 100))
// incomingImgView?.layoutIfNeeded()

view.layoutIfNeeded()

Upvotes: 1

Views: 2284

Answers (4)

torinpitchers
torinpitchers

Reputation: 1292

have you tried incomingImgView.sizeToFit() This method fits the view to the correct size for its parent view.

Upvotes: 0

Simen91
Simen91

Reputation: 73

I've been working with this exact issue for a while and came up with this solution for the class that I have made which inherits from UIImageView (note that you can probably just place it as an extension of UIImageView itself instead of creating a new class if this is the only thing you're changing):

func scaleAndCenterInParent(){
    //Scales and centers to superview
    if let screenSize = superview?.frame.size{

        let frameSize = self.frame.size


        if frameSize.width > screenSize.width || frameSize.height > screenSize.height{
            //Image exceeds screen in at least one direction
            var scale: CGFloat = 1
            let frameRatio = (frameSize.width)/(frameSize.height)

            if frameRatio >= 1{
                //landscape frame
                scale = screenSize.width/frameSize.width
            }else{
                //portrait frame
                scale = screenSize.height/frameSize.height
            }

            //apply transform to self (imageview)
            self.transform = self.transform.scaledBy(x: scale, y: scale)



            //center
            self.frame.origin.x = (superview!.bounds.midX - (frameSize.width*0.5))
            self.frame.origin.y = (superview!.bounds.midY - (frameSize.height*0.5))
        }
    }
}

EDIT: Note that you still need to set the .scaleAspectFit parameter, because this only changes the size of the frame. It retains the full image quality.

Upvotes: 0

Parth Adroja
Parth Adroja

Reputation: 13514

You are setting frame twice so the first time you are trying to set is replaced with frame incomingImgView?.frame = view.bounds so it will take the frame of view.bounds and not incomingImgView?.frame = CGRect(x: 0, y: 0, width: view.bounds.width , height: view.bounds.height).

Try the below code and check

   incomingImgView?.frame = CGRect(x: 0, y: 0, width: 100  , height: 100)
   incomingImgView?.contentMode = .scaleAspectFit    
   incomingImgView?.clipsToBounds = true
   viewContainer.addSubview(incomingImgView!)    

Upvotes: 0

Vikram Biwal
Vikram Biwal

Reputation: 2826

Please try this:

 incomingImgView?.frame = CGRect(x: 0, y: 0, width: viewContainer.bounds.width  , height:  viewContainer.bounds.height)

Upvotes: 2

Related Questions