attributed-string

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AttributedString Patterns

AttributedString 使用模式

Correct API shapes and patterns for Foundation's
AttributedString
. Covers creating styled text, applying attributes to ranges, text alignment, writing direction, line height control, text selection and editing, discontiguous substrings, and SwiftUI integration.
Foundation框架中
AttributedString
的正确API形式与使用模式,涵盖样式文本创建、范围属性应用、文本对齐、书写方向、行高控制、文本选择与编辑、非连续子字符串以及SwiftUI集成。

When 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进行文本选择文本编辑
  • 想要使用DiscontiguousAttributedSubstringRangeSet
  • 提及在SwiftUI中结合AttributedString使用TextEditor
  • 询问Swift中的富文本格式设置方法
  • 想要在AttributedString中替换修改文本
  • 提及paragraphStyletextSelectionAffinityAttributedTextSelection

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兼容性

APIMinimum VersionNotes
AttributedString
iOS 15 / macOS 12Swift-native replacement for NSAttributedString
AttributedString.font
iOS 15 / macOS 12Inline attribute
AttributedString.foregroundColor
iOS 15 / macOS 12Inline attribute
AttributedString.paragraphStyle
iOS 15 / macOS 12Uses NSMutableParagraphStyle
AttributedString.writingDirection
iOS 26 / macOS 26New in 2025
AttributedString.LineHeight
iOS 26 / macOS 26
.exact(points:)
,
.multiple(factor:)
,
.loose
AttributedString.alignment
iOS 26 / macOS 26
.left
,
.center
,
.right
AttributedTextSelection
iOS 26 / macOS 26Programmatic text selection
replaceSelection(_:withCharacters:)
iOS 26 / macOS 26Replace selection with plain characters
replaceSelection(_:with:)
iOS 26 / macOS 26Replace selection with AttributedString
DiscontiguousAttributedSubstring
iOS 26 / macOS 26Non-contiguous range selections
AttributedString.utf8
iOS 26 / macOS 26UTF-8 code unit view
TextEditor(text:selection:)
with AttributedString
iOS 26 / macOS 26SwiftUI rich text editing
.textSelectionAffinity(_:)
iOS 26 / macOS 26Control cursor affinity at line boundaries
API最低版本要求说明
AttributedString
iOS 15 / macOS 12Swift原生替代NSAttributedString的API
AttributedString.font
iOS 15 / macOS 12内联属性
AttributedString.foregroundColor
iOS 15 / macOS 12内联属性
AttributedString.paragraphStyle
iOS 15 / macOS 12基于NSMutableParagraphStyle实现
AttributedString.writingDirection
iOS 26 / macOS 262025年新增API
AttributedString.LineHeight
iOS 26 / macOS 26包含
.exact(points:)
,
.multiple(factor:)
,
.loose
三种模式
AttributedString.alignment
iOS 26 / macOS 26支持
.left
,
.center
,
.right
三种对齐方式
AttributedTextSelection
iOS 26 / macOS 26程序化文本选择API
replaceSelection(_:withCharacters:)
iOS 26 / macOS 26用普通字符替换选中内容
replaceSelection(_:with:)
iOS 26 / macOS 26用AttributedString替换选中内容
DiscontiguousAttributedSubstring
iOS 26 / macOS 26非连续范围选择API
AttributedString.utf8
iOS 26 / macOS 26UTF-8编码单元视图
支持AttributedString的
TextEditor(text:selection:)
iOS 26 / macOS 26SwiftUI富文本编辑组件
.textSelectionAffinity(_:)
iOS 26 / macOS 26控制光标在行边界处的位置偏好

Top 5 Mistakes

五大常见错误

#MistakeFix
1Using
NSAttributedString
in new Swift code
Use
AttributedString
(iOS 15+) for type-safe, Swift-native attributes
2Applying range-based attributes without checking the range existsAlways safely unwrap the result of
text.range(of:)
before subscripting
3Forgetting that
AttributedString
is a value type
Mutations require
var
, not
let
; assign attributes after declaring as
var
4Building
NSMutableParagraphStyle
when new alignment API is available
Use
text.alignment = .center
on iOS 26+ instead of manual paragraph styles
5Modifying the original string instead of the selection when using
replaceSelection
Pass the selection as
inout
and let the API update the selection range for you
序号错误操作修复方案
1在新Swift代码中使用
NSAttributedString
从iOS 15开始,使用类型安全的Swift原生API
AttributedString
2未检查范围是否存在就应用基于范围的属性在使用下标访问前,务必用
if let
安全解包
text.range(of:)
的结果
3忽略
AttributedString
是值类型的特性
要修改字符串需声明为
var
而非
let
;声明为
var
后再设置属性
4在已有新对齐API的情况下仍手动构建
NSMutableParagraphStyle
iOS 26及以上版本,直接使用
text.alignment = .center
替代手动段落样式
5使用
replaceSelection
时修改原字符串而非选中范围
将selection以
inout
方式传入,由API自动更新选中范围

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
}
PatternVerdict
var text = AttributedString("...")
then mutate
Correct
let text = AttributedString("...")
then mutate
Will not compile -- value type requires
var
Force-unwrapping
text.range(of:)!
Fragile -- use
if let
or
guard let
swift
let source = AttributedString("Hello, world!")
if let range = source.range(of: "world") {
    let substring = source[range]
    let extracted = AttributedString(substring) // 独立副本
}
模式结论
先声明
var text = AttributedString("...")
再修改
正确
先声明
let text = AttributedString("...")
再修改
无法编译——值类型需用
var
声明
强制解包
text.range(of:)!
易崩溃——使用
if let
guard let
安全解包

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 = style
swift
var paragraph = AttributedString("Centered paragraph of text")
let style = NSMutableParagraphStyle()
style.alignment = .center
paragraph.paragraphStyle = style

Modern Approach (iOS 26+)

新版实现(iOS 26+)

swift
var paragraph = AttributedString("Centered paragraph of text")
paragraph.alignment = .center
Available
TextAlignment
values:
ValueDescription
.left
Left-aligned text
.right
Right-aligned text
.center
Center-aligned text
swift
var paragraph = AttributedString("Centered paragraph of text")
paragraph.alignment = .center
可用的
TextAlignment
取值:
取值描述
.left
左对齐文本
.right
右对齐文本
.center
居中对齐文本

Writing Direction and Line Height

书写方向与行高

Writing Direction (iOS 26+)

书写方向设置(iOS 26+)

swift
var text = AttributedString("Hello عربي")
text.writingDirection = .rightToLeft
ValueDescription
.leftToRight
Standard LTR layout
.rightToLeft
RTL layout for Arabic, Hebrew, etc.
swift
var text = AttributedString("Hello عربي")
text.writingDirection = .rightToLeft
取值描述
.leftToRight
标准从左到右布局
.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
ModeUse Case
.exact(points:)
Pixel-perfect designs with fixed line heights
.multiple(factor:)
Proportional scaling relative to font size
.loose
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
模式使用场景
.exact(points:)
需要像素级精确设计的固定行高场景
.multiple(factor:)
与字体大小成比例缩放的场景
.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:
  • selection
    is passed as
    inout
    so the API updates the selection range after replacement.
  • Use
    withCharacters:
    for plain text,
    with:
    for styled replacements.
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
    inout
    方式传入,API会在替换后自动更新选中范围。
  • 普通文本替换用
    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)
}
OperationResult Type
text[range]
AttributedSubstring
(contiguous)
text[rangeSet]
DiscontiguousAttributedSubstring
(non-contiguous)
AttributedString(substring)
Flattened
AttributedString
copy
同时选择并操作多个非连续范围(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)
}
操作返回类型
text[range]
AttributedSubstring
(连续)
text[rangeSet]
DiscontiguousAttributedSubstring
(非连续)
AttributedString(substring)
合并后的
AttributedString
副本

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)
ValueBehavior
.upstream
Cursor stays at end of previous line
.downstream
Cursor moves to start of next line
控制光标在行边界处显示的行:
swift
TextEditor(text: $text, selection: $selection)
    .textSelectionAffinity(.upstream)
取值行为
.upstream
光标停留在上一行末尾
.downstream
光标移动到下一行开头

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
    AttributedString
    (not
    NSAttributedString
    ) for new Swift code
  • All range lookups safely unwrapped with
    if let
    or
    guard let
  • String declared as
    var
    before applying attributes
  • replaceSelection
    passes selection as
    inout
    (
    &selection
    )
  • 新Swift代码中使用
    AttributedString
    而非
    NSAttributedString
  • 所有范围查找都用
    if let
    guard let
    安全解包
  • 设置属性前将字符串声明为
    var
  • 使用
    replaceSelection
    时将selection以
    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 (
    if #available
    ) wrap newer APIs when supporting older deployment targets
  • 新API(对齐、书写方向、行高、选择)仅在iOS 26+ / macOS 26+环境使用
  • iOS 15-25版本使用旧版段落样式实现
  • 支持旧版本部署目标时,用
    if #available
    包裹新API

SwiftUI

SwiftUI相关

  • TextEditor(text:selection:)
    overload used for rich text editing (iOS 26+)
  • .textSelectionAffinity
    applied where cursor behavior at line wraps matters
  • .textSelection(.enabled)
    added to
    Text
    views that display user content
  • 使用支持AttributedString的
    TextEditor(text:selection:)
    重载实现富文本编辑(iOS 26+)
  • 在需要控制换行处光标行为时添加
    .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语言内容设置正确的书写方向

References

参考资料