Markdown with Moving Parts
We’re extremely proud to give you a small taste of what we’ve been working on at Moving Parts, our first component: A native SwiftUI View for Markdown rendering.
Calling Markdown a popular choice for adding inline styling to plain text would be an enormous understatement – Markdown is everywhere from Facebook Messenger to GitHub comments.
It comes as no surprise that iOS 15 is introducing native Markdown support in NSAttributedString
and SwiftUI’s Text
view. Apparently, great minds think alike because we have also been working on our own Markdown component.
Simply called Markdown
, this component supports the CommonMark spec and adds a few twists of its own that we believe will make it even more useful for the real-world use cases your apps encounter every day.
It’s also compatible with iOS 14 so you don’t have to wait for your customers to get onto iOS 15 before you can join in on the action.
Let’s start with the basics:
Markdown("""
© 2021 [Moving Parts](https://movingparts.io). All rights reserved.
""")
.font(.caption)
.multilineTextAlignment(.center)
.accentColor(.purple)
The most common use-case of Markdown in apps is to add simple inline styling to strings, especially links. This is especially relevant for localization, where a simple concatenation of Text
s individually applied attributes does not scale across languages.
Block Level Elements
That said, the benefits of Markdown are not limited to inline styles. It also offers a concise syntax for headings, lists, block-quotes and images. Let’s look at them in action:
Markdown("""
# Moving Parts `Markdown` view
> "Talent borrows, genius steals"
>
> – Plato, probably
We're happy to tease our Markdown view to the world for the first time.
Here are some reason it might be useful to you:
1. It supports iOS 14.
2. It supports block-level elements.
3. A warm, fuzzy feeling.
- Warm, fuzzy feeling subject to availability.
""")
Styling
It’s a cornerstone of our work at Moving Parts that all our components integrate as seamlessly as possible into your application. That’s why we made sure that you have a wide variety of ways to style any element to your hearts content.
We follow the established patterns of SwiftUI, so introducing a custom block quote style is as easy as defining a struct that conform to the associated BlockQuoteStyle
protocol, and building a view that matches whatever you feel look good.
struct CustomBlockQuoteStyle: BlockQuoteStyle {
@ViewBuilder
func makeBody(configuration: Configuration) -> some View {
Group {
configuration.content.lineSpacing(8)
HStack {
Spacer()
configuration.userInfo
.blockQuoteAttribution
.fixedSize()
}
.textCase(.uppercase)
}
}
}
But you don’t need to reach for a custom style for everything.
We made sure the appropriate SwiftUI modifiers carry through and are resolved meaningfully, be it foreground color or a custom font.
Markdown("""
> *"Sometimes the truth of a thing is not so much in the think of it,
> but in the feel of it."*
>
> -- Stanley Kubrick
""")
.detectBlockQuoteAttribution()
.blockQuoteStyle(CustomBlockQuoteStyle())
.font(.custom("Verdana", size: 16))
.foregroundColor(.white)
.padding()
.background(Color(red: 0.30, green: 0.32, blue: 0.35, opacity: 1).ignoresSafeArea())
Meaningful Extensions
You may have noticed the detectBlockQuoteAttribution
modifier in the previous example. It looks for a trailing attribution in a block quote and gives you an opportunity to style it differently from the rest.
Through small but meaningful extensions like this we hope we turn Markdown
into an expressive tool for your copy writers or editorial team to contribute to your application without having to resort to – dare we say it – a web view.
For example, using the sectionedBy(headingLevel:)
modifier, you can split your document into collapsible sections – a great fit for an FAQ or listing out Terms of Service for your app.
Markdown("""
# Frequently Asked Questions
## So how can I use this Markdown view?
Contact hello@movingparts.io to inquire about our service, we're open onboard our first select customers and would love for you to be one of them!
## What can I do in the meantime?
You can follow us [on Twitter](https://twitter.com/movingparts.io), subscribe to [our newsletter](https://movingparts.io) or tinker around with this playground.
## Who's behind Moving Parts?
Moving Parts was founded by Mike Evensen and Robb Böhnke.
""")
.sectioned(byHeadingLevel: 2)
.padding()
You can play around with the component by downloading our demo playground that contains a copy of this article as well as a pre-release version of the Moving Parts framework and we’d love to hear what you think.