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 🧐
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:Creating the same text with
RichStringKit
looks like this:Documentation 📖
Full documentation coming soon
Until then, take a look at some example usage.
Installation 💻
Swift Package Manager 📦
RichStringKit
can be added as a package dependency via Xcode or in yourPackage.swift
file.Xcode
https://github.com/moyerr/RichStringKit.git
0.0.1
Package.swift
Add the following value to the
dependencies
array: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@resultBuilder
similar to SwiftUI’sViewBuilder
. Closures, methods, and computed properties that returnsome RichString
can be decorated with the@RichStringBuilder
attribute 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,
RichStringKit
provides initializers onNSAttributedString
,AttributedString
, and SwiftUI’sText
view, all of which can either accept aRichString
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:Use the
Text
orAttributedString
initializers when working with SwiftUI:Modifiers
Style your text using the modifiers that
RichStringKit
provides, or by defining your own modifiers using theRichStringModifier
protocol and themodifier(_:)
method.Built-in Modifiers
RichStringKit
provides 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
RichStringModifier
protocol 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 onRichString
itself that incorporates the modifier:Then you can apply the highlight modifier to any rich string:
Advanced Usage
Formatted Strings
The
Format
type is provided to apply styling to formatted strings and their arguments independently.