I have requirement to load an advertisement image in my app and these are usually logos of companies.
The thing about logos is that while they can be of a specific height, their width would change.
So I started with a very simple solution, I uploaded a 90 x 20 png image in Firebase storage and then used the simples code:
Image(uiImage: image)
and this rendered the rendered the image at 90 x 20.
Some details left out is that I make a network request in the background to download this image and then - I feel this might be not relevant but can add code if needed.
The issue is that on an iPhone 16 (regular and pro) device, these image get really blurry.
So what I did was upload a 3x image but that previous code made the image grow massively as now the image dimensions were 270 x 60.
So to render the high quality image at the previous dimensions, I did the following:
Image(uiImage: image)
.resizable()
.renderingMode(.template)
.scaledToFit()
.frame(height: 20)
// The width of the parent view hosting this had a max width of infinity
Now this worked and the images were sharper. The issue with specifying a hardcoded height of 20, we ran into the issue with some company's logos being a bit taller so then we came up with a rule where the max height of the logo should be 28 so:
I achieve this via:
Image(uiImage: image)
.resizable()
.renderingMode(.template)
.tint(Constants.Colors.logo)
.scaledToFit()
.frame(height: min(image.size.height, 28))
This works for most of the use cases, however, if I want an image to render at 90 x 20 but at a high quality, and if I upload an image at 3x 270 x 60, it would not render at 90 x 20 but rather at 126 x 28 because 28 is the max height
While this might be acceptable, what would be a good way to render the 2x and 3x images at its original dimension rather than making the image grow to the 28 max height.
You should create the UIImage
using init(data:scale:)
. This initialiser allows you to specify the scale and it will be scaled accordingly when it is displayed.
Alternatively, create a CGDataProvider
using the Data
you got, then create a CGImage
from that (e.g. this initialiser for pngs). This CGImage
allows you to access the width and height in pixels, which you can use to calculate the scale. Finally, create a SwiftUI Image
using init(_:scale:orientation:label:)
, pass in the CGImage
and the scale. The label
is for accessibility.