SwiftUI Inline Text with an Image Positioned on the Right for a Multiline Text?

297 views Asked by At

I've got an image stored in the Assets folder, and my goal is to append it to a multiline text. I don't want to place it in an HStack; instead, I want it to appear at the end of the text, regardless of how many lines the text spans. Please refer to the image below for a visual example.

enter image description here

I'm aware that using Text(Image(systemName: "imageName")) is a suitable solution, especially for SFSymbols.

However, this approach isn't as effective when dealing with Asset images that exceed the font size of the text. The image below is by using the following code with an asset image.

Text(Image("info"))

enter image description here

1

There are 1 answers

0
Silviu Vranaw On

I found a solution and wrote a brief article about it. I'm open to exploring alternative approaches.

Inline Text and Image

This is the code that made things work for me:

struct InlineView: View {
   private var text = "This is a multi-line text. It has multiple lines. It has multiple lines. It has multiple lines. It has multiple lines. "
   private var image = "info" // Replace with your image name
   private let font: Font = .system(size: 17)

   var body: some View {
       Text(text)
           .font(font)
       + Text("\(getCustomImage())")
   }

   private func getCustomImage(color: Color = .gray, newSize: CGSize = CGSize(width: 17, height: 17)) -> Text {
       if let image = UIImage(named: image),
          let newImage = convertImageToNewFrame(image: image, newFrameSize: newSize) {
           return Text(
               Image(uiImage: newImage)
                   .renderingMode(.template)
           )
           .baselineOffset(-1.5)
           .foregroundStyle(color)
       }
       return Text(Image(systemName: "heart.fill"))
   }

   func convertImageToNewFrame(image: UIImage, newFrameSize: CGSize) -> UIImage? {
       UIGraphicsBeginImageContextWithOptions(newFrameSize, false, 0.0)
       image.draw(in: CGRect(origin: .zero, size: newFrameSize))
       let newImage = UIGraphicsGetImageFromCurrentImageContext()
       UIGraphicsEndImageContext()
       return newImage
   }
}