💰 RichStringKit 🔡


GitHub Workflow Status Updated

RichStringKit 是一个用于在 Swift 中构建富文本的声明式 DSL。

目录

  1. 动机 🧐
  2. 文档 📖
  3. 安装 💻
  4. 用法 🔡

动机 🧐

NSAttributedString 是一个用于创建富文本的强大工具,但使用起来可能很繁琐且容易出错。考虑以下富文本

Image of an attributed string that reads 'For the love of Swift' with the Swift programming language logo

使用 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

Swift Package Manager 📦

RichStringKit 可以通过 Xcode 或在您的 Package.swift 文件中添加为包依赖项。

Xcode

Package.swift

将以下值添加到 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 编程语言》的结果构建器部分

便捷初始化器

为了方便起见,RichStringKitNSAttributedStringAttributedString 和 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 时,使用 TextAttributedString 初始化器

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 中的属性键。当前可用的修饰符方法有

  1. .backgroundColor(_:)
  2. .baselineOffset(_:)
  3. .font(_:)
  4. .foregroundColor(_:)
  5. .kern(_:)
  6. .link(_:)
  7. .strikethroughStyle(_:)
  8. .underlineColor(_:)
  9. .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