WWDC 2020:
Text
now provides an initializer that accepts a singleImage
, this blog post will be updated or removed to reflect that. For now here’s the correct code.
struct ContentView : View {
@ObservedObject var character: Character
var body: some View {
HStack {
Text(Image(character.imageName)
.resizable())
Text(character.name)
}
.font(.title)
}
}
Often you need to include images inline in text, while being mindful of supporting all of the various user-customizable sizes of text, not to mention the accessibility sizes:
One way to do this is by creating a custom SF Symbol, but that involves individually drawing or hinting each possible size. This obviously gives the optimal result, but it’s not necessarily something we have the resource to do. In the case of user-supplied imagery such as a character portrait, it’s not even an option available to us.
There’s a nice trick to achieving this with any resizable image, and it builds on what we learned in views choose their own sizes, and secondary views.
Recall that a secondary view receives as its proposed size the chosen size of the view it’s attached to.
So what we need to do is attach the resizable Image
as a secondary
view to a Text
view that will inherit the font-size from the
environment and choose its size accordingly.
We can then remove the Text
itself from the output using the .hidden
modifier, while leaving the Image
overlaid on top visible:
struct ContentView : View {
@ObservedObject var character: Character
var body: some View {
HStack {
Text("M")
.hidden()
.overlay(
Image(character.imageName)
.resizable()
.aspectRatio(contentMode: .fit))
Text(character.name)
}
.font(.title)
}
}