Attributed TextはiOS SDKの機構で、NSAttributedStringおよびNSMutableAttributedStringクラスによって表現され、単一のテキストストリングの異なる部分に複数のスタイルを適用できます。一般的なNSStringとは異なり、Attributed Stringは文字だけでなく、各範囲に対する属性辞書も保存します:フォント、色、行間、陰影、配弃です。Apple Developer Documentationによると、Attributed StringはUILabel、UITextView、UITextFieldにおける書式付きテキスト表示の基礎です。WebKitやサードパーティライブラリなしでテキストをスタイリングする標準的な方法です。
メインポイント
NSAttributedStringはFoundationフレームワークのクラスで、文字範囲に結びつけられた名前付き属性のセットを持つストリングを表現します。各属性はキーバリゥー組です:キーは定数(NSFontAttributeName、NSForegroundColorAttributeName)で定義され、値は対応するオブジェクト(UIFont、UIColor)です。属性はNSRangeを通じて文字の範囲に適用されます。
このクラスはすべてのAppleプラットフォームで利用可能です:iOS (2.0+)、macOS、tvOS、watchOS。NSAttributedStringは不可変です — 一度作成されると、その属性は固定されます。ダイナミックな変更にはNSMutableAttributedStringが使用され、NSAttributedStringを継承し、setAttributes、addAttributes、addAttribute、removeAttributeメソッドを追加します。
NSStringはスタイル情報のない単純な文字列です。textを通じてUILabelに渡されたどのようなテキストも、単一のフォント、色、サイズで表示されます。attributedTextを通じて渡されたNSAttributedStringは、各文字が独自の属性セットを持つことができます。UILabel、UITextView、UITextFieldはNSAttributedStringを自動的に認識し、その属性に従ってテキストをレンダリングします。
内部的に、NSAttributedStringはテキストを持つNSStringと属性範囲の配列を保存します。各範囲はNSRange構造体と属性辞書で表現されます。レンダリング中、システムは範囲を紹り、各セクションに対応する属性を適用します。効率は属性スイッチの回数に依存します — 短いセクションでの頻繁な変更はレンダリング時間を増やします。
NSAttributedStringの属性はUIKit(iOS)およびAppKit(macOS)で定義された定数で、各々がテキストの視覚的スタイリングの特定の要素に対応します。すべての属性はNSAttributedString.Keyストリングであり、その値は特定のクラスのオブジェクトです。属性は文字レベル(文字に影響)と段落レベル(段落に影響)に分けられます。
文字レベルの属性にはフォント(NSFontAttributeName)、テキストの色(NSForegroundColorAttributeName)、背景色(NSBackgroundColorAttributeName)、下線(NSUnderlineStyleAttributeName)、取り消し線(NSStrikethroughStyleAttributeName)、陰影(NSShadowAttributeName)が含まれます。段落レベルの属性はNSParagraphStyleAttributeNameを通じて設定され、配弃、インデント、行間、タブ止めを制御します。
NSLinkAttributeNameはテキスト中にクリッカブルなリンクを作成します:値はURLまたはストリングです。UITextViewはインタラクションが有効な場合、これらのリンクを自動的に処理します。NSAttachmentAttributeNameはテキスト内にインライン要素として表示されるNSTextAttachment—画像を埋め込むことができます。これはアイコン、絵文字、またはカスタムビューを含むテキストを作成するために使用されます。
各NSAttributedString属性は正確にタイプ付けされた値を持ちます。iOS開発で最もよく使われる属性を見てみましょう。フォントはUIFontオブジェクトを通じて、色はUIColorを通じて、行間はNSMutableParagraphStyleを通じて設定され、これにより配弃、インデント、間隔を単一のオブジェクトで構成できます。
| 属性キー | 値のタイプ | 目的 |
|---|---|---|
| NSFontAttributeName | UIFont | テキストのフォント |
| NSForegroundColorAttributeName | UIColor | テキストの色 |
| NSBackgroundColorAttributeName | UIColor | テキストの背景色 |
| NSUnderlineStyleAttributeName | NSNumber (Int) | 下線のスタイル |
| NSParagraphStyleAttributeName | NSParagraphStyle | 段落設定 |
| NSKernAttributeName | NSNumber (Float) | 文字間スペース(ケールニング) |
NSParagraphStyleは段落属性のコンテナです:alignment、lineSpacing、paragraphSpacing、firstLineHeadIndent、lineBreakMode、minimumLineHeightなど。これらのパラメーターを変更するには、NSMutableParagraphStyleを作成し、必要なプロパティを設定し、そのオブジェクトをNSParagraphStyleAttributeName属性の値として渡します。これがNSAttributedStringで行間を制御する唯一の方法です。
NSShadowはテキストに陰影を追加できます:shadowOffset、shadowBlurRadius、shadowColorのパラメーターが陰影の位置、ぼかし、色を設定します。下線および取り消し線の属性はスタイルの組み合わせを受け付けます:NSUnderlineStyle.single、.double、.thick、.patternDash、.patternDot。線の太さと色を正確に制御するには、NSUnderlineColorAttributeNameおよびNSStrikethroughColorAttributeNameが使用されます。
SwiftでNSAttributedStringを作成するには、テキストと属性辞書を指定するイニシャライザを使うか、NSMutableAttributedStringを使って歩々にスタイルを適用します。基本的なアプローチは、テキスト全体に対する属性辞書を定義し、その後特定の範囲に属性を追加または変更することです。
簡単な例 — ストリング全体にフォント、色、配弃を設定します。属性辞書はNSAttributedStringのイニシャライザに渡されます。辞書のキーはNSAttributedString.Key定数であり、値は対応するUIKitオブジェクトです。これはテキスト全体が一様に書式設定される場合の基本ケースです。
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 16),
.foregroundColor: UIColor.darkGray,
.paragraphStyle: let style = NSMutableParagraphStyle()
style.alignment = .center
style.lineSpacing = 4
return style
]
let attributedString = NSAttributedString(
string: "Hello world",
attributes: attributes
)
label.attributedText = attributedString
テキストはsystemFont 16、ダークグレーの色、中央揃え、行間4ptで表示されます。このアプローチは静的な見出しやボタンに便利です。
NSMutableAttributedStringはテキストの異なる部分に異なるスタイルを適用できます。addAttributeメソッドは範囲に単一の属性を追加し、addAttributesは属性辞書を追加します。setAttributesメソッドは範囲のすべての存在する属性を新しいものに置き換えます。これがハイライト付きテキストを作成するための主要なツールです。
let text = "Price: 1999 rubles"
let attributed = NSMutableAttributedString(string: text)
attributed.addAttribute(.foregroundColor,
value: UIColor.green, range: NSRange(location: 6, length: 4))
attributed.addAttribute(.font,
value: UIFont.boldSystemFont(ofSize: 20), range: NSRange(location: 6, length: 4))
label.attributedText = attributed
語“1999”は緑色で太字になり、他のテキストは標準のままです。NSRangeは手動で計算されます — 特に絵文字や複合Unicode文字を扱う際には、文字列の長さを正確にカウントすることが重要です。
NSMutableAttributedStringはテキストや属性をダイナミックに変更するためのメソッドを提供します:append、insert、replace、delete、setAttributes、addAttribute、removeAttribute、enumerateAttributes。これにより、異なるソースからのテキスト構築、スタイルの組み合わせ、インタフェースイベントへの対応が可能です。
不可変のNSAttributedStringとは異なり、変可バージョンは新しいオブジェクトを作成せずに内容を変更できます。これはテキストエディタ、チャット、フォームなど、ユーザーがテキストを編集でき、スタイルを保存する必要がある場合に重要です。
メッセンジャーでは、各メッセージにはユーザー名(太字)、メッセージテキスト(普通)、時刻(灰色)があります。NSMutableAttributedStringは、対応する属性を持つ部分を必要な順序で追加して、一度にこうしたストリングを構築できます。
let result = NSMutableAttributedString()
let name = NSAttributedString(string: "Anna: ",
attributes: [.font: UIFont.boldSystemFont(ofSize: 15)])
let message = NSAttributedString(string: "Hello, how are you?",
attributes: [.font: UIFont.systemFont(ofSize: 15)])
let time = NSAttributedString(string: " 12:30",
attributes: [.foregroundColor: UIColor.gray])
result.append(name)
result.append(message)
result.append(time)
label.attributedText = result
結果は、3つのスタイル済みセクションを持つ単一のストリングです。Appendは自動的にNSRangeを計算し、位置を手動で計算する必要はありません。このアプローチは何つのフラグメントにも対応できます。
enumerateAttributes(in:options:using:)メソッドは指定された範囲内のすべての属性範囲を繰り返します。これは書式分析に便利です:すべてのリンクを見つける、特定の属性の色を変更する、またはテキストをHTMLにエクスポートするなど。クロージャには、現在のセクションの属性辞書とNSRangeが渡されます。
UIKitでテキストを表示するすべての主要なUIコンポーネントは、attributedTextプロパティを通じてNSAttributedStringをサポートしています。UILabelは静的なスタイル済みテキストを表示し、UITextViewは編集とリンクをサポートし、UITextFieldはプレースホルダーと入力テキストに属性を別々に受け付けます。
UILabelはスタイル済みテキストを表示するための最もライトなコンポーネントです。すべての文字レベルの属性をサポートしますが、クリッカブルなリンクを自動的に処理しません(そのためにはUITextViewが必要です)。UILabelは見出し、ラベル、短い書式付きテキストに最適です。
UITextViewはNSLinkAttributeNameを処理し、リンクをインタラクティブな要素として表示します。この機能を有効にするには、isSelectable = trueおよびisEditable = falseを設定します。リンクをタップすると、デリゲートはtextView(_:shouldInteractWith:in:interaction:)を受け取ります。UITextViewはまた、テキスト内の画像にNSTextAttachmentをサポートします。
let text = "Details on developer.apple.com"
let attributed = NSMutableAttributedString(string: text)
attributed.addAttribute(.link,
value: URL(string: "https://developer.apple.com")!,
range: NSRange(location: 0, length: text.count))
textView.attributedText = attributed
textView.isSelectable = true
textView.isEditable = false
isSelectableとisEditableを設定すると、テキストエリアは静的なテキストブロックとして動作しますが、リンクはアクティブのままです。UITextViewDelegateがタップ時の動作を制御します。
Core TextはNSAttributedStringと直接組み合わせて動作するAppleの低レベルテキストレンダリングフレームワークです。UIKitとは異なり、Core TextはNSAttributedStringを直接表示オブジェクトとして使用しません — 代わりに、それをCTFramesetterに変換し、さらにCTFrameに変換し、Core Graphicsコンテキストでレンダリングします。これにより、行レイアウトとグリフを完全に制御できます。
Core Textの使用は、カスタムなテキストレイアウト(段組、画像の回り込み、テキストの回転、非標準な改行)に適しています。Core TextのNSMutableParagraphStyleには、UIKitでは利用できない属性が含まれています:kCTParagraphStyleSpecifierMaximumLineSpacing、kCTParagraphStyleSpecifierLineBreakMode(追加モード付き)。
NSAttributedStringはUIKitとCore Textの間でシームレスに移行できます。なぜなら、両方のフレームワークが同じタイプを扱うからです。UIKitの属性(NSFontAttributeName、NSForegroundColorAttributeName)はCore Textによって自動的に認識され、その逆(kCTFontAttributeName)もUIKitで読み取られます。これにより、簡単な任務にはUIKitを、カスタムレンダリングにはCore Textを、同じNSAttributedStringオブジェクトで使い分けることができます。
よくある質問
NSStringはスタイル情報のない単純なテキストのみを保存します。NSAttributedStringは各文字範囲に属性辞書を付加します。textプロパティを通じてUILabelに渡されると、NSStringはプレーンテキストとして表示されます。attributedTextを通じてNSAttributedStringが渡されると、すべての属性(異なるフォント、色、間隔)が単一のストリングで適用されます。
addAttributes(_:range:)メソッドを属性辞書と使用します:addAttributes([.font: font, .foregroundColor: color], range: range)。単一の属性を追加または変更するには、addAttribute(_:value:range:)を使用します。setAttributesメソッドは、範囲内のすべての存在する属性を渡された属性に置き換えます。
NSMutableParagraphStyleを作成し、lineSpacingプロパティを設定し、それをNSParagraphStyleAttributeName属性の値として渡します。完全な制御のためには、minimumLineHeight、maximumLineHeight、paragraphSpacing、lineBreakMode、alignmentも利用可能です。ParagraphStyleが行間を制御する唯一の方法です。
はい、SwiftUIはiOS 15+でText(attributedString:)を通じてNSAttributedStringをサポートしています。古いバージョンでは、UILabelまたはUITextViewとともにUIViewRepresentableを使用します。SwiftUIはまた、Markdown駐式の文法を持つ宣言的な書式設定のために、独自のAttributedStringタイプ(FoundationではなくSwiftUI)も提供しています。
boundingRect(with:options:context:)メソッドを使用します。これは、指定された属性でストリングを表示するのに必要なCGRectを返します。optionsパラメーター:[.usesLineFragmentOrigin, .usesFontLeading]は行間とフォントメトリックを考慮します。制限された行数のUILabelには、sizeThatFitsを使用します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。