attributed-string
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAttributedString Patterns
AttributedString 使用模式
Correct API shapes and patterns for Foundation's . Covers creating styled text, applying attributes to ranges, text alignment, writing direction, line height control, text selection and editing, discontiguous substrings, and SwiftUI integration.
AttributedStringFoundation框架中的正确API形式与使用模式,涵盖样式文本创建、范围属性应用、文本对齐、书写方向、行高控制、文本选择与编辑、非连续子字符串以及SwiftUI集成。
AttributedStringWhen This Skill Activates
本技能适用场景
Use this skill when the user:
- Asks about AttributedString creation or manipulation
- Wants to style text with fonts, colors, underlines, or other attributes
- Mentions text alignment, writing direction, or line height
- Asks about text selection or text editing with AttributedString
- Wants to work with DiscontiguousAttributedSubstring or RangeSet
- Mentions TextEditor with AttributedString in SwiftUI
- Asks about rich text formatting in Swift
- Wants to replace or modify text within an AttributedString
- Mentions paragraphStyle, textSelectionAffinity, or AttributedTextSelection
当用户有以下需求时,使用本技能:
- 询问AttributedString的创建或操作方法
- 希望为文本设置字体、颜色、下划线等样式
- 提及文本对齐、书写方向或行高设置
- 询问如何结合AttributedString进行文本选择或文本编辑
- 想要使用DiscontiguousAttributedSubstring或RangeSet
- 提及在SwiftUI中结合AttributedString使用TextEditor
- 询问Swift中的富文本格式设置方法
- 想要在AttributedString中替换或修改文本
- 提及paragraphStyle、textSelectionAffinity或AttributedTextSelection
Decision Tree
决策树
What do you need with AttributedString?
|
+-- Create or style text
| |
| +-- Simple inline attributes (font, color)
| | --> Creating and Styling section
| |
| +-- Paragraph-level formatting (alignment, line height)
| --> Text Alignment and Formatting section
|
+-- Control text layout
| |
| +-- Writing direction (LTR / RTL)
| | --> Writing Direction and Line Height section
| |
| +-- Line spacing / height
| --> Writing Direction and Line Height section
|
+-- Edit or select text programmatically
| |
| +-- Replace selection with characters or AttributedString
| | --> Text Selection and Editing section
| |
| +-- Work with multiple non-contiguous ranges
| --> DiscontiguousAttributedSubstring section
|
+-- Display in SwiftUI
--> SwiftUI Integration section你需要对AttributedString进行什么操作?
|
+-- 创建或设置文本样式
| |
| +-- 简单内联属性(字体、颜色)
| | --> 查看「创建与样式设置」章节
| |
| +-- 段落级格式设置(对齐、行高)
| --> 查看「文本对齐与格式设置」章节
|
+-- 控制文本布局
| |
| +-- 书写方向(LTR / RTL)
| | --> 查看「书写方向与行高」章节
| |
| +-- 行间距 / 行高
| --> 查看「书写方向与行高」章节
|
+-- 以编程方式编辑或选择文本
| |
| +-- 用普通字符或AttributedString替换选中内容
| | --> 查看「文本选择与编辑」章节
| |
| +-- 处理多个非连续范围
| --> 查看「DiscontiguousAttributedSubstring」章节
|
+-- 在SwiftUI中展示
--> 查看「SwiftUI集成」章节API Availability
API兼容性
| API | Minimum Version | Notes |
|---|---|---|
| iOS 15 / macOS 12 | Swift-native replacement for NSAttributedString |
| iOS 15 / macOS 12 | Inline attribute |
| iOS 15 / macOS 12 | Inline attribute |
| iOS 15 / macOS 12 | Uses NSMutableParagraphStyle |
| iOS 26 / macOS 26 | New in 2025 |
| iOS 26 / macOS 26 | |
| iOS 26 / macOS 26 | |
| iOS 26 / macOS 26 | Programmatic text selection |
| iOS 26 / macOS 26 | Replace selection with plain characters |
| iOS 26 / macOS 26 | Replace selection with AttributedString |
| iOS 26 / macOS 26 | Non-contiguous range selections |
| iOS 26 / macOS 26 | UTF-8 code unit view |
| iOS 26 / macOS 26 | SwiftUI rich text editing |
| iOS 26 / macOS 26 | Control cursor affinity at line boundaries |
| API | 最低版本要求 | 说明 |
|---|---|---|
| iOS 15 / macOS 12 | Swift原生替代NSAttributedString的API |
| iOS 15 / macOS 12 | 内联属性 |
| iOS 15 / macOS 12 | 内联属性 |
| iOS 15 / macOS 12 | 基于NSMutableParagraphStyle实现 |
| iOS 26 / macOS 26 | 2025年新增API |
| iOS 26 / macOS 26 | 包含 |
| iOS 26 / macOS 26 | 支持 |
| iOS 26 / macOS 26 | 程序化文本选择API |
| iOS 26 / macOS 26 | 用普通字符替换选中内容 |
| iOS 26 / macOS 26 | 用AttributedString替换选中内容 |
| iOS 26 / macOS 26 | 非连续范围选择API |
| iOS 26 / macOS 26 | UTF-8编码单元视图 |
支持AttributedString的 | iOS 26 / macOS 26 | SwiftUI富文本编辑组件 |
| iOS 26 / macOS 26 | 控制光标在行边界处的位置偏好 |
Top 5 Mistakes
五大常见错误
| # | Mistake | Fix |
|---|---|---|
| 1 | Using | Use |
| 2 | Applying range-based attributes without checking the range exists | Always safely unwrap the result of |
| 3 | Forgetting that | Mutations require |
| 4 | Building | Use |
| 5 | Modifying the original string instead of the selection when using | Pass the selection as |
| 序号 | 错误操作 | 修复方案 |
|---|---|---|
| 1 | 在新Swift代码中使用 | 从iOS 15开始,使用类型安全的Swift原生API |
| 2 | 未检查范围是否存在就应用基于范围的属性 | 在使用下标访问前,务必用 |
| 3 | 忽略 | 要修改字符串需声明为 |
| 4 | 在已有新对齐API的情况下仍手动构建 | iOS 26及以上版本,直接使用 |
| 5 | 使用 | 将selection以 |
Creating and Styling
创建与样式设置
Basic Initialization
基础初始化
swift
// Plain text
let plain = AttributedString("Hello, world!")
// With attributes applied inline
var bold = AttributedString("Bold text")
bold.font = .boldSystemFont(ofSize: 16)swift
// 纯文本
let plain = AttributedString("Hello, world!")
// 内联设置属性
var bold = AttributedString("Bold text")
bold.font = .boldSystemFont(ofSize: 16)Applying Attributes to Ranges
为指定范围应用属性
swift
var text = AttributedString("Styled text")
text.foregroundColor = .red
text.backgroundColor = .yellow
text.font = .systemFont(ofSize: 14)
// Attribute on a specific range
if let range = text.range(of: "Styled") {
text[range].underlineStyle = .single
text[range].underlineColor = .blue
}swift
var text = AttributedString("Styled text")
text.foregroundColor = .red
text.backgroundColor = .yellow
text.font = .systemFont(ofSize: 14)
// 为特定范围设置属性
if let range = text.range(of: "Styled") {
text[range].underlineStyle = .single
text[range].underlineColor = .blue
}Creating from a Substring
从子字符串创建
swift
let source = AttributedString("Hello, world!")
if let range = source.range(of: "world") {
let substring = source[range]
let extracted = AttributedString(substring) // standalone copy
}| Pattern | Verdict |
|---|---|
| Correct |
| Will not compile -- value type requires |
Force-unwrapping | Fragile -- use |
swift
let source = AttributedString("Hello, world!")
if let range = source.range(of: "world") {
let substring = source[range]
let extracted = AttributedString(substring) // 独立副本
}| 模式 | 结论 |
|---|---|
先声明 | 正确 |
先声明 | 无法编译——值类型需用 |
强制解包 | 易崩溃——使用 |
Text Alignment and Formatting
文本对齐与格式设置
Legacy Approach (iOS 15+)
旧版实现(iOS 15+)
swift
var paragraph = AttributedString("Centered paragraph of text")
let style = NSMutableParagraphStyle()
style.alignment = .center
paragraph.paragraphStyle = styleswift
var paragraph = AttributedString("Centered paragraph of text")
let style = NSMutableParagraphStyle()
style.alignment = .center
paragraph.paragraphStyle = styleModern Approach (iOS 26+)
新版实现(iOS 26+)
swift
var paragraph = AttributedString("Centered paragraph of text")
paragraph.alignment = .centerAvailable values:
TextAlignment| Value | Description |
|---|---|
| Left-aligned text |
| Right-aligned text |
| Center-aligned text |
swift
var paragraph = AttributedString("Centered paragraph of text")
paragraph.alignment = .center可用的取值:
TextAlignment| 取值 | 描述 |
|---|---|
| 左对齐文本 |
| 右对齐文本 |
| 居中对齐文本 |
Writing Direction and Line Height
书写方向与行高
Writing Direction (iOS 26+)
书写方向设置(iOS 26+)
swift
var text = AttributedString("Hello عربي")
text.writingDirection = .rightToLeft| Value | Description |
|---|---|
| Standard LTR layout |
| RTL layout for Arabic, Hebrew, etc. |
swift
var text = AttributedString("Hello عربي")
text.writingDirection = .rightToLeft| 取值 | 描述 |
|---|---|
| 标准从左到右布局 |
| 适用于阿拉伯语、希伯来语等的从右到左布局 |
Line Height (iOS 26+)
行高设置(iOS 26+)
swift
var multiline = AttributedString(
"This is a paragraph\nwith multiple lines\nof text."
)
// Exact point value
multiline.lineHeight = .exact(points: 32)
// Multiplier of the default line height
multiline.lineHeight = .multiple(factor: 2.5)
// System-defined loose spacing
multiline.lineHeight = .loose| Mode | Use Case |
|---|---|
| Pixel-perfect designs with fixed line heights |
| Proportional scaling relative to font size |
| Comfortable reading spacing chosen by the system |
swift
var multiline = AttributedString(
"This is a paragraph\nwith multiple lines\nof text."
)
// 固定行高值
multiline.lineHeight = .exact(points: 32)
// 基于默认行高的倍数
multiline.lineHeight = .multiple(factor: 2.5)
// 系统定义的宽松行间距
multiline.lineHeight = .loose| 模式 | 使用场景 |
|---|---|
| 需要像素级精确设计的固定行高场景 |
| 与字体大小成比例缩放的场景 |
| 系统预设的舒适阅读行间距场景 |
Text Selection and Editing
文本选择与编辑
Replacing Selected Text (iOS 26+)
替换选中文本(iOS 26+)
swift
var text = AttributedString("Here is my dog")
var selection = AttributedTextSelection(range: text.range(of: "dog")!)
// Replace with plain characters
text.replaceSelection(&selection, withCharacters: "cat")
// Replace with an AttributedString
let replacement = AttributedString("horse")
text.replaceSelection(&selection, with: replacement)Key points:
- is passed as
selectionso the API updates the selection range after replacement.inout - Use for plain text,
withCharacters:for styled replacements.with:
swift
var text = AttributedString("Here is my dog")
var selection = AttributedTextSelection(range: text.range(of: "dog")!)
// 用普通字符替换
text.replaceSelection(&selection, withCharacters: "cat")
// 用AttributedString替换
let replacement = AttributedString("horse")
text.replaceSelection(&selection, with: replacement)核心要点:
- 以
selection方式传入,API会在替换后自动更新选中范围。inout - 普通文本替换用,带样式的替换用
withCharacters:。with:
DiscontiguousAttributedSubstring
DiscontiguousAttributedSubstring
Select and manipulate multiple non-contiguous ranges at once (iOS 26+).
swift
let text = AttributedString("Select multiple parts of this text")
if let range1 = text.range(of: "Select"),
let range2 = text.range(of: "text") {
let rangeSet = RangeSet([range1, range2])
var substring = text[rangeSet] // DiscontiguousAttributedSubstring
substring.backgroundColor = .yellow
// Flatten into a single contiguous AttributedString
let combined = AttributedString(substring)
}| Operation | Result Type |
|---|---|
| |
| |
| Flattened |
同时选择并操作多个非连续范围(iOS 26+)。
swift
let text = AttributedString("Select multiple parts of this text")
if let range1 = text.range(of: "Select"),
let range2 = text.range(of: "text") {
let rangeSet = RangeSet([range1, range2])
var substring = text[rangeSet] // DiscontiguousAttributedSubstring类型
substring.backgroundColor = .yellow
// 合并为单个连续的AttributedString
let combined = AttributedString(substring)
}| 操作 | 返回类型 |
|---|---|
| |
| |
| 合并后的 |
UTF-8 View
UTF-8视图
Access raw UTF-8 code units (iOS 26+):
swift
let text = AttributedString("Hello")
for codeUnit in text.utf8 {
print(codeUnit)
}访问原始UTF-8编码单元(iOS 26+):
swift
let text = AttributedString("Hello")
for codeUnit in text.utf8 {
print(codeUnit)
}SwiftUI Integration
SwiftUI集成
TextEditor with AttributedString and Selection (iOS 26+)
结合AttributedString与选择功能的TextEditor(iOS 26+)
swift
struct SuggestionTextEditor: View {
@State var text: AttributedString = ""
@State var selection = AttributedTextSelection()
var body: some View {
VStack {
TextEditor(text: $text, selection: $selection)
SuggestionsView(
substrings: getSubstrings(
text: text,
indices: selection.indices(in: text)
)
)
}
}
}swift
struct SuggestionTextEditor: View {
@State var text: AttributedString = ""
@State var selection = AttributedTextSelection()
var body: some View {
VStack {
TextEditor(text: $text, selection: $selection)
SuggestionsView(
substrings: getSubstrings(
text: text,
indices: selection.indices(in: text)
)
)
}
}
}Text Selection Affinity
文本选择位置偏好
Control which line the cursor appears on when positioned at a line boundary:
swift
TextEditor(text: $text, selection: $selection)
.textSelectionAffinity(.upstream)| Value | Behavior |
|---|---|
| Cursor stays at end of previous line |
| Cursor moves to start of next line |
控制光标在行边界处显示的行:
swift
TextEditor(text: $text, selection: $selection)
.textSelectionAffinity(.upstream)| 取值 | 行为 |
|---|---|
| 光标停留在上一行末尾 |
| 光标移动到下一行开头 |
Displaying Styled Text in SwiftUI
在SwiftUI中展示样式文本
swift
// Simple display
Text(attributedString)
// With text selection enabled
Text(attributedString)
.textSelection(.enabled)swift
// 简单展示
Text(attributedString)
// 启用文本选择
Text(attributedString)
.textSelection(.enabled)Review Checklist
检查清单
Correctness
正确性
- Using (not
AttributedString) for new Swift codeNSAttributedString - All range lookups safely unwrapped with or
if letguard let - String declared as before applying attributes
var - passes selection as
replaceSelection(inout)&selection
- 新Swift代码中使用而非
AttributedStringNSAttributedString - 所有范围查找都用或
if let安全解包guard let - 设置属性前将字符串声明为
var - 使用时将selection以
replaceSelection方式传入(inout)&selection
Platform and Versioning
平台与版本兼容
- New APIs (alignment, writingDirection, lineHeight, selection) gated to iOS 26+ / macOS 26+
- Legacy paragraph style approach used for iOS 15-25 targets
- Availability checks () wrap newer APIs when supporting older deployment targets
if #available
- 新API(对齐、书写方向、行高、选择)仅在iOS 26+ / macOS 26+环境使用
- iOS 15-25版本使用旧版段落样式实现
- 支持旧版本部署目标时,用包裹新API
if #available
SwiftUI
SwiftUI相关
- overload used for rich text editing (iOS 26+)
TextEditor(text:selection:) - applied where cursor behavior at line wraps matters
.textSelectionAffinity - added to
.textSelection(.enabled)views that display user contentText
- 使用支持AttributedString的重载实现富文本编辑(iOS 26+)
TextEditor(text:selection:) - 在需要控制换行处光标行为时添加修饰符
.textSelectionAffinity - 展示用户内容的视图添加
Text修饰符.textSelection(.enabled)
Accessibility
无障碍适配
- Foreground and background color combinations meet contrast requirements
- Styled text does not rely solely on color to convey meaning (add underline, bold, or icons)
- Writing direction set correctly for RTL language content
- 前景色与背景色组合符合对比度要求
- 样式文本不单纯依赖颜色传递信息(添加下划线、粗体或图标)
- 为RTL语言内容设置正确的书写方向