Home > Blockchain >  SwiftUI Image from UIImage is still stretched after setting ascpectMode: .fit
SwiftUI Image from UIImage is still stretched after setting ascpectMode: .fit

Time:08-06

I'm struggling to show a SwiftUI Image correctly when creating it from UIImage with the initialiser Image(uiImage: UIImage).

The code I'm using is

private var rightViewImage: Image

public var body: some View {
        ....
                  rightViewImage
                        .resizable()
                        .renderingMode(.template)
                        .scaledToFit()
                        .foregroundColor(.blue)
                        .frame(width: 20, height: 20)

}

and setting the variable in a method with

if let image = UIImage(systemName: "mic") {
   rightViewImage = Image(uiImage: image)
}

I get a stretched version of the image

1

instead of the correctly scaled one, which is this

2

It seems like the .scaledToFit() is not working, it renders it like a .fill.

Is this a bug?

CodePudding user response:

UIImage(systemName:) provides a completely different image dimension and resolution from Image(systemName:).

For this case, you should this instead:

 Image(systemName: "mic")
            .resizable()
            .renderingMode(.template)
            .scaledToFit()
            .foregroundColor(.blue)
            .frame(width: 20, height: 20)

This is what rendered by Image():

enter image description here

This is what rendered by UIImage():

enter image description here

CodePudding user response:

The other answer will get the job done.

But what if you can't use an SF Symbol and want to preserve the aspect ratio? In that case, use the .aspectRatio() modifier:

Image("my-custom-image")
    .resizable()
    .aspectRatio(contentMode: .fit)

That will give an image that is as large as can fit in the parent view without stretching.

It looks like the question might be about some text paired with an image though. The best way to handle that is not to use resizable() at all. SF Symbols have a bunch of variations that match the system font. And Image(systemName:) will give a size and weight based on the current font. So you can do something like this and the image will match the text:

HStack {
    Text("Here's a label")
    Image(systemName: "mic")
        .foregroundColor(.blue)
}
.font(.title.bold())

That's a better bet than resizing by hand because it will match the iOS system design and look 'right.'

  • Related