AttributedString 是 Swift 标准库中的一个字符串类型,用于处理带有属性的字符串(比如颜色、字体、链接等)。它是苹果在 iOS 15 / macOS 12 引入的现代化替代品,用来取代旧的 NSAttributedString。
基本概念
普通的String只包含纯文本:
let text = "Hello, World!" // 只是文字

AttributedString 可以给文字添加样式和属性:
var attributedText = AttributedString("Hello, World!")
attributedText.foregroundColor = .red // 红色文字
attributedText.font = .largeTitle // 大标题字体
attributedText.underlineStyle = .single // 下划线

在SwiftUI中,如果想要显示富文本,如给文字加醋、显示不同颜色,添加链接,可以使用AttributedString。
基本用法
1、创建方法
import SwiftUI
// 方法 1:从普通字符串创建
var text1 = AttributedString("Hello, Swift!")
// 方法 2:从 Markdown 创建
var text2 = try! AttributedString(markdown: "This is **bold** and *italic*")
// 方法 3:从 String Literal 创建
var text3: AttributedString = "Simple text"
// 方法 4:从 NSAttributedString 创建
let attr = try AttributedString(nsAttributedString)
2、设置属性
var text = AttributedString("Hello, World!")
// 设置文字颜色
text.foregroundColor = .blue
// 设置字体
text.font = .title
// 设置背景色
text.backgroundColor = .yellow
// 在 SwiftUI 中显示
Text(text)

常用属性
var text = AttributedString("示例文本")
// 文字样式
text.font = .title // 字体
text.foregroundColor = .blue // 文字颜色
text.backgroundColor = .yellow // 背景色
text.underlineStyle = .single // 下划线
text.strikethroughStyle = .single // 删除线
text.baselineOffset = 10 // 基线偏移
// 链接
text.link = URL(string: "https://apple.com") // 超链接
// 段落样式(需要 ParagraphStyle)
var paragraphStyle = ParagraphStyle()
paragraphStyle.alignment = .center // 居中对齐
paragraphStyle.lineSpacing = 5 // 行间距
常用方法
1、查找range
if let range = attr.range(of: "World") {
attr[range].foregroundColor = .red
}
可以通过range查找并修改局部元素,每次只返回当前搜索范围内的第一个匹配区间。
2、遍历runs
for run in attr.runs {
print(run.attributes)
}
可以分析每一段样式。
3、遍历某个属性
for (value, range) in attr.runs[\.font] {
print(value, range)
}
4、桥接回NSAttributedString
let ns = NSAttributedString(attr)
5、SwiftUI显示
Text(attr)
拼接与组合
1、拼接
let a = AttributedString("Hello ")
let b = AttributedString("World")
let c = a + b
样式各自保留。
2、append
var attr = AttributedString("Hello ")
attr.append(AttributedString("World"))
文本语义属性
在自定义渲染 / Markdown 结构分析时,可以使用文本语义属性判断是否为标题、段落、粗体。
1、presentationIntent:判断标题、列表、引用、段落。
2、inlinePresentationIntent:判断强调、粗体、斜体、行内代码。
示例:
let attr = try! AttributedString(markdown: """
# Title
This is **bold** and *italic* text with `code`.
> Quote line
""")
for run in attr.runs {
let text = attr[run.range]
print("文本:", String(text.characters))
if let block = text.presentationIntent {
print("块级语义:", block)
}
if let inline = text.inlinePresentationIntent {
print("行内语义:", inline)
}
print("------")
}
输出内容:
文本: Title
块级语义: [header 1 (id 1)]
------
文本: This is
块级语义: [paragraph (id 2)]
------
文本: bold
块级语义: [paragraph (id 2)]
行内语义: NSInlinePresentationIntent(rawValue: 2)
------
…
Markdown支持
AttributedString支持显示Markdown。
// 基础 Markdown
let markdown1 = try! AttributedString(markdown: """
# 标题
这是 **粗体** 和 *斜体*。
还有 [链接](https://apple.com)。
""")
// 在 SwiftUI 中显示
Text(markdown1)

Markdown可以根据不同的选项进行解析:
// 完整 Markdown(包括标题、列表、分段换行、行内语法等)
let fullMarkdown = try! AttributedString(
markdown: "# 标题\n\n这是正文",
options: AttributedString.MarkdownParsingOptions(
interpretedSyntax: .full
)
)
// 仅行内语法(支持粗体、斜体、链接,不支持标题、列表、引用)
let inlineOnly = try! AttributedString(
markdown: "这是 **粗体** 和 *斜体*",
options: AttributedString.MarkdownParsingOptions(
interpretedSyntax: .inlineOnly
)
)
// 内联元素 + 保留空白
let inlinePreserving = try! AttributedString(
markdown: "保留 多个空格",
options: AttributedString.MarkdownParsingOptions(
interpretedSyntax: .inlineOnlyPreservingWhitespace
)
)
注意:在实际测试中发现SwiftUI #标题可能无法显示,换行可能无法在 .full 选项中显示。
总结
AttributedString是结构化富文本,可以显示字体属性、支持Range操作和Markdown语义。
