NSAttributedString is a powerful tool for creating rich text, but using it can be cumbersome and error-prone. Consider the following attributed text:
Creating this text with NSAttributedString might look something like this:
let attributedString = NSMutableAttributedString(
string: "For the love of Swift ",
attributes: [.font: UIFont.systemFont(ofSize: 40)]
)
let strongAttributes: [NSAttributedString.Key: Any] = [
.foregroundColor: UIColor.swift,
.font: UIFont.boldSystemFont(ofSize: 40)
]
if let swiftLogo = UIImage(systemName: "swift") {
let swiftLogoAttachment = NSTextAttachment(image: swiftLogo)
let swiftLogoString = NSAttributedString(attachment: swiftLogoAttachment)
attributedString.append(swiftLogoString)
if let swiftRange = attributedString.string.range(of: "Swift") {
let strongRange = swiftRange.lowerBound ..< attributedString.string.endIndex
attributedString.addAttributes(
strongAttributes,
range: NSRange(strongRange, in: attributedString.string)
)
}
}
Creating the same text with RichStringKit looks like this:
let richString = NSAttributedString {
"For the love of "
Group {
"Swift "
Attachment(systemName: "swift")
}
.foregroundColor(.swift)
.font(.boldSystemFont(ofSize: 40))
}
The mechanism that enables RichStringKit’s declarative DSL is the RichStringBuilder, which is a @resultBuilder similar to SwiftUI’s ViewBuilder. Closures, methods, and computed properties that return some RichString can be decorated with the @RichStringBuilder attribute to enable the DSL within them. For example:
@RichStringBuilder
var richText: some RichString {
"Underlined text"
.underlineStyle(.single)
" and "
"strikethrough text"
.strikethroughStyle(.single)
}
For convenience, RichStringKit provides initializers on NSAttributedString, AttributedString, and SwiftUI’s Text view, all of which can either accept a RichString or a @RichStringBuilder closure. So you can start start using rich strings with your UI framework of choice.
Use the NSAttributedString initializers when working with UIKit:
let label = UILabel()
label.attributedString = NSAttributedString {
"UIKit"
.font(.boldSystemFont(ofSize: 14))
" is "
"fun"
.kern(4)
.foregroundColor(.green)
}
Use the Text or AttributedString initializers when working with SwiftUI:
struct ContentView: View {
var body: some View {
Text {
"SwiftUI"
.font(.boldSystemFont(ofSize: 14))
" is also "
"fun"
.kern(4)
.foregroundColor(.green)
}
}
}
Modifiers
Style your text using the modifiers that RichStringKit provides, or by defining your own modifiers using the RichStringModifier protocol and the modifier(_:) method.
Built-in Modifiers
RichStringKit provides many modifiers for styling text, most of which map directly to attribute keys from NSAttributedString.Key. The modifier methods that are currently available are:
.backgroundColor(_:)
.baselineOffset(_:)
.font(_:)
.foregroundColor(_:)
.kern(_:)
.link(_:)
.strikethroughStyle(_:)
.underlineColor(_:)
.underlineStyle(_:)
More attributes will be added soon (#7).
Combining Modifiers
Adopt the RichStringModifier protocol when you want to create a reusable modifier that you can apply to any RichString. The example below combines modifiers to create a new modifier that you can use to create highlighted text with a yellow background and a dark foreground:
You can apply modifier(_:) directly to a rich string, but a more common and idiomatic approach uses modifier(_:) to define an extension on RichString itself that incorporates the modifier:
Then you can apply the highlight modifier to any rich string:
var body: some RichText {
"Draw the reader's attention to important information "
"by applying a highlight"
.highlighted()
}
Advanced Usage
Formatted Strings
The Format type is provided to apply styling to formatted strings and their arguments independently.
Format("For the love of %@") {
Group {
"Swift "
Attachment(systemName: "swift")
}
.foregroundColor(.swift)
.font(.boldSystemFont(ofSize: 40))
}
.font(.systemFont(ofSize: 40))
Note:RichStringKit currently supports only the %@ format specifier. If your use case requires more advanced formatting, you can apply the formatting before inserting it into the final format string. For example:
💰 RichStringKit 🔡
RichStringKit is a declarative DSL for building rich text in Swift.
Table of Contents
Motivation 🧐
NSAttributedStringis a powerful tool for creating rich text, but using it can be cumbersome and error-prone. Consider the following attributed text:Creating this text with
NSAttributedStringmight look something like this:Creating the same text with
RichStringKitlooks like this:Documentation 📖
Full documentation coming soon
Until then, take a look at some example usage.
Installation 💻
Swift Package Manager 📦
RichStringKitcan be added as a package dependency via Xcode or in yourPackage.swiftfile.Xcode
https://github.com/moyerr/RichStringKit.git0.0.1Package.swift
Add the following value to the
dependenciesarray:Include it as a dependency for one or more of your targets:
Usage 🔡
Rich String Result Builder
The mechanism that enables RichStringKit’s declarative DSL is the
RichStringBuilder, which is a@resultBuildersimilar to SwiftUI’sViewBuilder. Closures, methods, and computed properties that returnsome RichStringcan be decorated with the@RichStringBuilderattribute to enable the DSL within them. For example:For more general information about Swift’s result builder types, see the Result Builder section of The Swift Programming Language.
Convenience Initializers
For convenience,
RichStringKitprovides initializers onNSAttributedString,AttributedString, and SwiftUI’sTextview, all of which can either accept aRichStringor a@RichStringBuilderclosure. So you can start start using rich strings with your UI framework of choice.Use the
NSAttributedStringinitializers when working with UIKit:Use the
TextorAttributedStringinitializers when working with SwiftUI:Modifiers
Style your text using the modifiers that
RichStringKitprovides, or by defining your own modifiers using theRichStringModifierprotocol and themodifier(_:)method.Built-in Modifiers
RichStringKitprovides many modifiers for styling text, most of which map directly to attribute keys fromNSAttributedString.Key. The modifier methods that are currently available are:.backgroundColor(_:).baselineOffset(_:).font(_:).foregroundColor(_:).kern(_:).link(_:).strikethroughStyle(_:).underlineColor(_:).underlineStyle(_:)More attributes will be added soon (#7).
Combining Modifiers
Adopt the
RichStringModifierprotocol when you want to create a reusable modifier that you can apply to anyRichString. The example below combines modifiers to create a new modifier that you can use to create highlighted text with a yellow background and a dark foreground:You can apply
modifier(_:)directly to a rich string, but a more common and idiomatic approach usesmodifier(_:)to define an extension onRichStringitself that incorporates the modifier:Then you can apply the highlight modifier to any rich string:
Advanced Usage
Formatted Strings
The
Formattype is provided to apply styling to formatted strings and their arguments independently.