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
instead of the correctly scaled one, which is this
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():
This is what rendered by UIImage():
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.'