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
}
}