Insert Image into SwiftUI Text
Reading time: 1 min
This recipe shows how to insert an Image into SwiftUI Text, so that the resulting view is still a Text instance.
The end result looks like this:

This solution works for SwiftUI 2+ (iOS 14+, macOS 11+).
Text has an initializer that takes an Image and converts it into a Text, which can then be concatenated with other Texts into a single Text:
(Text("This image")
+ Text(Image("icon")) // HERE
+ Text("is our logo."))
.font(.title)
This all works fine until you need to resize the image. Using the frame modifier results in a View, which then can't be passed into a Text initializer:
// THIS DOESN'T WORK
(Text("This image")
+ Text(Image("icon").resizable().frame(width: 32, height: 32))
+ Text("is our logo."))
.font(.title)
The trick to make this work is to use the method from this recipe, which converts any View into an UIImage. Here's a quick extension that captures the functionality of resizing an Image while also returning an Image:
extension Image {
func resizedAsImage(width: CGFloat? = nil,
height: CGFloat? = nil) -> Image {
Image(uiImage: self
.resizable()
.frame(width: width, height: height)
.snapshot) // check the other recipe for this extension
}
}
Then, you can insert a resized image into any Text:
(Text("This image")
+ Text(Image("icon").resizedAsImage(width: 96, height: 96))
+ Text("is our logo."))
.font(.title)
What doesn't work - using AttributedString
Some of you may know that in UIKit, it's possible to insert an image into a Label using NSAttributedString that wraps an NSTextAttachment, like this:
let imageAttachment = NSTextAttachment(image: UIImage(named: "icon")!)
let imageString = NSAttributedString(attachment: imageAttachment)
Then, theoretically, you could convert NSAttributedString into an AttributedString which you can then plug into a Text:
let attrStr = try! AttributedString(myString, including: \.uiKit)
...
Text(attrStr)
However, this doesn't work and the image isn't shown. The issue isn't explicitly documented or explained anywhere.