I will prefix this by saying I have quite limited Swift and SwiftUI experience, so there might be some obvious things that I have missed.
My problem is split into multiple areas of concern
- I want to render a text link using markdown within a Text view in SwiftUI
- I want the label for this link to contain an image alongside some text so that the text and image are both clickable
- I need this to be done inside a Text view which I can then append to the end of another Text view.
Some context
I have several paragraphs of text, each one coming from a specific source which I want to provide a link to. The link should be inline with the text and at the end of each paragraph, and should be in the format "Source <icon>". I believe SwiftUI’s support for markdown is the easiest way to achieve this, as it allows a simple Text view to contain a hyperlink by doing: Text(.init("[Source](https://example.com)"))
. This has got me quite far, but I am missing the crucial step of including the icon as part of the link label. As of now, I have been forced to add the icon after the actual link text as per the example below.
So my question boils down to: Is there a way to render an image inside a markdown string in SwiftUI?
Simplified example of my code setup
import SwiftUI
struct Paragraph {
text: String
url: String
}
struct ParagraphView: View {
let paragraph: Paragraph
var body: some View {
Text(paragraph.text)
// Less than ideal solution I have currently
+ Text(.init(" [Source]((paragraph.url)) "))
+ Text(Image(systemName: "star")) // Example icon
}
}
Ideally, I would like to do something like this
struct ParagraphView: View {
let paragraph: Paragraph
var body: some View {
Text(paragraph.text)
+ Text(.init(" [Source (IMAGE)]((paragraph.url))"))
}
}
I have tried using both AttributedString and NSAttributedString to achieve this
struct ParagraphView: View {
let paragraph: Paragraph
var markdown: String {
let str = NSMutableAttributedString(string: " [Source ")
let iconAttachment = NSTextAttachment()
iconAttachment.image = UIImage(systemName: "star")
let iconText = NSAttributedString(attachment: iconAttachment)
str.append(iconText)
str.append(NSAttributedString(string: "]((paragraph.url))"))
return str.string
}
var body: some View {
Text(paragraph.text)
// Link works, but image is not rendered
+ Text(.init(markdown))
}
}
2
Answers
Instead of using markdown to display an image within some text,
you could try a different simple but versatile approach using two
HStack
a.onTapGesture
withopenURL
,as shown in the example code.
Currently, it seems that Images still aren’t supported by Swift UI.
Source
There are probably other libraries out there for this, you’ll have to pick one if you want to add images in markdown.
This article also discusses the issue and introduces this package which is compatible with GitHub’s Markdown Spec.
Because of that compatibility, you’ll then be able to use all the normal markdown that you’re used to:
↓↓