Scaling Image To Fit Certain Dimensions and Keep Aspect Ratio SwiftUI

9.1k Views Asked by At

I understand that it is impossible to use the .scaledToFit() modifier on an image with a frame of 120 and 430, with a frame modifier like .frame(height: 100, width: 100) and expect the image to somehow keep the aspect ratio and fit the frame of width 100 and heigh 100.

So, it seems like the only way around this would be to force the user to crop their image into a square when uploading it with the image picker. Is this possible in SwiftUI/is there something I'm missing here?

Thanks

2

There are 2 best solutions below

1
On

You can use aspectRatio(contentMode:):

Image("imageName")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 100, height: 100)
0
On

If I understand your problem correctly, you want to put non-square image (120x430) in a square box (100x100). To do that you can scale image preserving it's aspect ratio. Image will be scaled to maximum height or width (depending on target width and height).

Check out this article: https://www.robertpieta.com/resize-uiimage-no-stretching-swift/

Here is copy and paste solution:

extension UIImage {
  func scalePreservingAspectRatio(width: Int, height: Int) -> UIImage {
    let widthRatio = CGFloat(width) / size.width
    let heightRatio = CGFloat(height) / size.height
    
    let scaleFactor = min(widthRatio, heightRatio)
    
    let scaledImageSize = CGSize(
      width: size.width * scaleFactor,
      height: size.height * scaleFactor
    )
    
    let format = UIGraphicsImageRendererFormat()
    format.scale = 1
    
    let renderer = UIGraphicsImageRenderer(
      size: scaledImageSize,
      format: format
    )
    
    let scaledImage = renderer.image { _ in
      self.draw(in: CGRect(
        origin: .zero,
        size: scaledImageSize
      ))
    }
    
    return scaledImage
  }
}