RichStringKit 是一个用于在 Swift 中构建富文本的声明式 DSL。
NSAttributedString
是一个用于创建富文本的强大工具,但使用起来可能很繁琐且容易出错。考虑以下富文本
使用 NSAttributedString
创建此文本可能如下所示
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)
)
}
}
使用 RichStringKit
创建相同的文本如下所示
let richString = NSAttributedString {
"For the love of "
Group {
"Swift "
Attachment(systemName: "swift")
}
.foregroundColor(.swift)
.font(.boldSystemFont(ofSize: 40))
}
完整文档即将推出
在此之前,请查看一些 用法示例。
RichStringKit 需要 Swift 5.7
RichStringKit
可以通过 Xcode 或在您的 Package.swift
文件中添加为包依赖项。
https://github.com/moyerr/RichStringKit.git
0.0.1
将以下值添加到 dependencies
数组
.package(url: "https://github.com/moyerr/RichStringKit", from: "0.0.1")
将其作为依赖项包含到一个或多个目标中
.target(
name: "<your-target>",
dependencies: [
.product(name: "RichStringKit", package: "RichStringKit"),
]
)
启用 RichStringKit 声明式 DSL 的机制是 RichStringBuilder
,它是一个 @resultBuilder
,类似于 SwiftUI 的 ViewBuilder
。返回 some RichString
的闭包、方法和计算属性可以使用 @RichStringBuilder
属性进行装饰,以在其中启用 DSL。例如
@RichStringBuilder
var richText: some RichString {
"Underlined text"
.underlineStyle(.single)
" and "
"strikethrough text"
.strikethroughStyle(.single)
}
有关 Swift 结果构建器类型的更多一般信息,请参阅 《Swift 编程语言》的结果构建器部分。
为了方便起见,RichStringKit
在 NSAttributedString
、AttributedString
和 SwiftUI 的 Text
视图上提供了初始化器,所有这些初始化器都可以接受 RichString
或 @RichStringBuilder
闭包。因此,您可以开始将富字符串与您选择的 UI 框架一起使用。
当使用 UIKit 时,使用 NSAttributedString
初始化器
let label = UILabel()
label.attributedString = NSAttributedString {
"UIKit"
.font(.boldSystemFont(ofSize: 14))
" is "
"fun"
.kern(4)
.foregroundColor(.green)
}
当使用 SwiftUI 时,使用 Text
或 AttributedString
初始化器
struct ContentView: View {
var body: some View {
Text {
"SwiftUI"
.font(.boldSystemFont(ofSize: 14))
" is also "
"fun"
.kern(4)
.foregroundColor(.green)
}
}
}
使用 RichStringKit
提供的修饰符或通过使用 RichStringModifier
协议和 modifier(_:)
方法定义您自己的修饰符来设置文本样式。
RichStringKit
提供了许多用于设置文本样式的修饰符,其中大多数直接映射到 NSAttributedString.Key
中的属性键。当前可用的修饰符方法有
.backgroundColor(_:)
.baselineOffset(_:)
.font(_:)
.foregroundColor(_:)
.kern(_:)
.link(_:)
.strikethroughStyle(_:)
.underlineColor(_:)
.underlineStyle(_:)
更多属性将很快添加 (#7)。
当您想要创建一个可重用的修饰符,可以应用于任何 RichString
时,请采用 RichStringModifier
协议。下面的示例组合了修饰符,以创建一个新的修饰符,您可以使用它来创建带有黄色背景和深色前景的高亮文本
struct Highlight: RichStringModifier {
func body(_ content: Content) -> some RichString {
content
.foregroundColor(.black)
.backgroundColor(.yellow)
}
}
您可以将 modifier(_:)
直接应用于富字符串,但更常见和惯用的方法是使用 modifier(_:)
在 RichString
本身上定义一个扩展,其中包含修饰符
extension RichString {
func highlighted() -> some RichString {
modifier(Highlight())
}
}
然后您可以将高亮修饰符应用于任何富字符串
var body: some RichText {
"Draw the reader's attention to important information "
"by applying a highlight"
.highlighted()
}
提供 Format
类型以独立地将样式应用于格式化字符串及其参数。
Format("For the love of %@") {
Group {
"Swift "
Attachment(systemName: "swift")
}
.foregroundColor(.swift)
.font(.boldSystemFont(ofSize: 40))
}
.font(.systemFont(ofSize: 40))
注意:
RichStringKit
目前仅支持%@
格式说明符。如果您的用例需要更高级的格式化,您可以在将其插入到最终格式字符串之前应用格式化。例如let receiptLine = AttributedString { Format("Iced latte: %@") { String(format: "%10.2f", -4.49) .foregroundColor(.red) } } // Iced latte: -4.49