mcpField
A
attributed-string

attributed-string

github.com/rshankrasデザイン・UI83877 回インストール14 週間前に更新
リポジトリ

attributed-string について

Swift開発者向けのFoundation AttributedStringガイドです。テキスト装飾、段落書式、選択範囲の編集、SwiftUI連携を扱い、APIの使い方と対応OSの条件を説明します。

主な機能

  1. 01フォント・色・下線の設定
  2. 02配置・方向・行の高さの制御
  3. 03テキスト選択範囲の置換と編集
  4. 04不連続なテキスト範囲の処理
  5. 05SwiftUIでのリッチテキスト表示と編集

活用シーン

  1. 01テキストの一部にスタイルを適用
  2. 02段落の配置や行間を調整
  3. 03エディターで選択テキストを置換
  4. 04SwiftUIのリッチテキスト編集画面を作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rshankras/claude-code-apple-skills --skill attributed-string

インストール後、Claude Code で/attributed-stringを入力して読み込まれたか確認します。

詳細

AttributedString のパターン

Foundation の AttributedString の正しい API の形とパターンです。スタイル付きテキストの作成、範囲への属性の適用、テキストの配置、書字方向、行の高さの制御、テキストの選択と編集、非連続部分文字列、SwiftUI との統合を扱います。

このスキルが有効になる場合

次のような質問には、このスキルを使用してください。

  • AttributedString の作成や操作について質問されたとき
  • フォント、色、下線などの属性でテキストにスタイルを適用したいとき
  • テキストの配置、書字方向、行の高さに言及されたとき
  • AttributedString を使ったテキストの選択やテキストの編集について質問されたとき
  • DiscontiguousAttributedSubstring や RangeSet を使いたいとき
  • SwiftUI で AttributedString を使った TextEditor に言及されたとき
  • Swift でのリッチテキストの書式設定について質問されたとき
  • AttributedString 内のテキストを置換または変更したいとき
  • paragraphStyle、textSelectionAffinity、AttributedTextSelection に言及されたとき

判断フロー

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

API の利用可能状況

API最低バージョン備考
AttributedStringiOS 15 / macOS 12NSAttributedString に代わる Swift ネイティブの型
AttributedString.paragraphStyleiOS 15 / macOS 12NSMutableParagraphStyle を使用
AttributedString.writingDirectioniOS 26 / macOS 262025 年に追加
AttributedString.LineHeightiOS 26 / macOS 26.exact(points:)、.multiple(factor:)、.loose
AttributedString.alignmentiOS 26 / macOS 26.left、.center、.right
AttributedTextSelectioniOS 26 / macOS 26プログラムによるテキストの選択
replaceSelection(_:withCharacters:)iOS 26 / macOS 26選択範囲を通常の文字で置換
replaceSelection(_:with:)iOS 26 / macOS 26選択範囲を AttributedString で置換
DiscontiguousAttributedSubstringiOS 26 / macOS 26非連続範囲の選択
AttributedString.utf8iOS 26 / macOS 26UTF-8 コード単位のビュー
AttributedString を使った TextEditor(text:selection:)iOS 26 / macOS 26SwiftUI のリッチテキスト編集
.textSelectionAffinity(_:)iOS 26 / macOS 26行境界でのカーソルのアフィニティを制御

よくある間違いトップ 5

#間違い修正方法
1新しい Swift コードで NSAttributedString を使用する型安全で Swift ネイティブの属性を使える iOS 15 以降では AttributedString を使用します
2範囲が存在するか確認せずに、範囲ベースの属性を適用する添字アクセスの前に、text.range(of:) の結果を必ず安全にアンラップします
3AttributedString が値型であることを忘れる変更には let ではなく var が必要です。var として宣言してから属性を割り当てます
4新しい配置 API が使えるのに NSMutableParagraphStyle を作成するiOS 26 以降では、手動で段落スタイルを設定する代わりに text.alignment = .center を使用します
5replaceSelection の使用時に、選択範囲ではなく元の文字列を変更する選択範囲を inout として渡すと、API が選択範囲を更新します

作成とスタイル設定

基本的な初期化
// Plain text
let plain = AttributedString("Hello, world!")

// With attributes applied inline
var bold = AttributedString("Bold text")
bold.font = .boldSystemFont(ofSize: 16)
範囲への属性の適用
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
}
部分文字列からの作成
let source = AttributedString("Hello, world!")
if let range = source.range(of: "world") {
    let substring = source[range]
    let extracted = AttributedString(substring) // standalone copy
}
パターン判定
var text = AttributedString("...") を作成してから変更する正しい
let text = AttributedString("...") を作成してから変更するコンパイルできません。値型には var が必要です
text.range(of:)! で強制アンラップする不安定です。if let または guard let を使用します

テキストの配置と書式設定

従来の方法(iOS 15 以降)
var paragraph = AttributedString("Centered paragraph of text")
let style = NSMutableParagraphStyle()
style.alignment = .center
paragraph.paragraphStyle = style
最新の方法(iOS 26 以降)
var paragraph = AttributedString("Centered paragraph of text")
paragraph.alignment = .center

使用できる TextAlignment の値:

値説明
.left左揃えのテキスト
.right右揃えのテキスト
.center中央揃えのテキスト

書字方向と行の高さ

書字方向(iOS 26 以降)
var text = AttributedString("Hello عربي")
text.writingDirection = .rightToLeft
値説明
.leftToRight標準的な左から右へのレイアウト
.rightToLeftアラビア語やヘブライ語などの右から左へのレイアウト
行の高さ(iOS 26+)
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
モード用途
.exact(points:)固定の行の高さを使用するピクセル単位で正確なデザイン
.multiple(factor:)フォントサイズに対する比例的な拡大縮小
.looseシステムが選択する、読みやすい行間

テキストの選択と編集

選択したテキストの置換(iOS 26+)
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)

要点:プレーンテキストには withCharacters: を、スタイル付きの置換には with: を使用します。

DiscontiguousAttributedSubstring

複数の連続していない範囲を一度に選択して操作します(iOS 26+)。

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)
}

UTF-8ビュー

生のUTF-8コード単位にアクセスします(iOS 26+):

let text = AttributedString("Hello")
for codeUnit in text.utf8 {
    print(codeUnit)
}

SwiftUIとの統合

AttributedStringと選択範囲を使ったTextEditor(iOS 26+)
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)
                )
            )
        }
    }
}
テキスト選択のアフィニティ

行の境界にカーソルを置いたときに、カーソルを表示する行を制御します:

TextEditor(text: $text, selection: $selection)
    .textSelectionAffinity(.upstream)

.upstream はカーソルを前の行の末尾に保持し、.downstream は次の行の先頭に移動します。

SwiftUIでのスタイル付きテキストの表示
// Simple display
Text(attributedString)

// With text selection enabled
Text(attributedString)
    .textSelection(.enabled)

レビューチェックリスト

正確性
  • 新しいSwiftコードでは NSAttributedString ではなく AttributedString を使用している
  • すべての範囲検索を if let または guard let で安全にアンラップしている
  • 属性を適用する前に、文字列を var として宣言している
  • replaceSelection に選択範囲を inout(&selection)として渡している
プラットフォームとバージョン管理
  • 新しいAPI(alignment、writingDirection、lineHeight、selection)をiOS 26+/macOS 26+向けに条件付きで使用している
  • iOS 15~25を対象とする場合は、従来の段落スタイルの方法を使用している
  • 古いデプロイメントターゲットにも対応する場合、新しいAPIを利用する箇所を可用性チェック(if #available)で囲んでいる
SwiftUI
  • リッチテキスト編集には TextEditor(text:selection:) のオーバーロードを使用している(iOS 26+)
  • 行の折り返し時のカーソル動作が重要な箇所に .textSelectionAffinity を適用している
  • ユーザーコンテンツを表示する Text ビューに .textSelection(.enabled) を追加している
アクセシビリティ
  • 前景色と背景色の組み合わせがコントラスト要件を満たしている
  • スタイル付きテキストが意味を伝える手段として色だけに依存していない(下線、太字、アイコンを追加している)
  • RTL言語のコンテンツに適切な書字方向を設定している

参考資料

コメント