NSAttributedString — що це, форматування тексту та атрибути в iOS

Автор: IT Sectr Опубліковано: 2026-07-23 Час читання: 9 хв

NSAttributedString — це клас із Foundation framework в iOS SDK, що представляє рядок із набором атрибутів форматування, застосованих до окремих символів або діапазонів тексту. На відміну від звичайного NSString, NSAttributedString зберігає не лише символи Unicode, але й словник атрибутів (шрифт, колір, міжсимвольний інтервал, вирівнювання) для кожного сегмента рядка. За даними Apple Developer Documentation (2026), NSAttributedString є основою для відображення форматованого тексту в усіх UI-компонентах iOS.

Головне

  • NSAttributedString — незмінний рядок з атрибутами, де кожному символу або діапазону відповідає словник атрибутів NSAttributedStringKey
  • NSMutableAttributedString — змінна версія з методами addAttribute, setAttributes, replaceCharacters для модифікації атрибутів у runtime
  • Основні атрибути: .font, .foregroundColor, .paragraphStyle, .kern, .underlineStyle, .strikethroughStyle, .link, .backgroundColor
  • NSMutableParagraphStyle — допоміжний об'єкт для завдання вирівнювання, міжрядкового інтервалу, відступів та напрямку тексту
  • UILabel, UITextView, UITextField підтримують attributedText для відображення атрибутованих рядків

Що таке NSAttributedString?

NSAttributedString — це фундаментальний клас iOS/macOS для роботи з форматованим текстом. Він розширює можливості NSString, додаючи до рядка атрибути — словник пар ключ-значення, де ключ — константа NSAttributedStringKey (наприклад, .font, .foregroundColor), а значення — відповідний об'єкт (UIFont, UIColor). Кожен символ у рядку може мати свій набір атрибутів, що дозволяє реалізувати змішане форматування в одному рядку.

Архітектура NSAttributedString базується на концепції атрибутних діапазонів (attribute runs). Якщо задати атрибут .font = UIFont.boldSystemFont(ofSize: 16) для діапазону символів 0..5, усі символи цього діапазону відобразяться жирним шрифтом. Інші символи можуть мати інший шрифт або не мати атрибуту взагалі. При відображенні атрибутованого рядка система UIKit об'єднує характеристики з різних діапазонів та рендерить текст одноманітно.

NSAttributedString незмінний — після створення його атрибути та вміст не можуть бути змінені. Для модифікації існує підклас NSMutableAttributedString, який надає методи для додавання, видалення та зміни атрибутів у будь-яких діапазонах. Ця відмінність важлива для багатопотоковості: незмінний NSAttributedString потокобезпечний, а NSMutableAttributedString — ні.

Основні атрибути форматування тексту

NSAttributedString підтримує близько 40 стандартних атрибутів, визначених у NSAttributedStringKey. Кожен атрибут впливає на певний аспект зовнішнього вигляду тексту: шрифт, колір, положення, підкреслення, тінь, міжсимвольний інтервал, абзацний стиль та гіперпосилання. Для завдання атрибуту використовується константа NSAttributedStringKey, і їй присвоюється об'єкт відповідного типу.

Ключ атрибутуТип значенняПризначення
.fontUIFontШрифт та розмір тексту
.foregroundColorUIColorКолір тексту
.backgroundColorUIColorКолір фону під текстом
.paragraphStyleNSParagraphStyleВирівнювання, міжрядковий інтервал, відступи
.kernNSNumber (Float)Міжсимвольний інтервал (кернінг)
.underlineStyleNSUnderlineStyle (Int)Стиль підкреслення (одинарний, подвійний, товстий, візерунок)
.strikethroughStyleNSUnderlineStyle (Int)Стиль закреслення
.linkNSURLURL для інтерактивного гіперпосилання
.shadowNSShadowТінь тексту з offset, blurRadius та кольором
.baselineOffsetNSNumber (Float)Зміщення тексту відносно базової лінії

NSParagraphStyle — абзацне форматування

NSMutableParagraphStyle — об'єкт, що керує візуальними характеристиками абзацу: вирівнювання (.alignment: .left, .center, .right, .justified), міжрядковий інтервал (.lineSpacing), відстань між абзацами (.paragraphSpacing), відступ першого рядка (.firstLineHeadIndent), відступ зліва та справа (.headIndent, .tailIndent) та напрямок тексту (.baseWritingDirection). ParagraphStyle застосовується до діапазону, який включає символи нового рядка, якщо потрібне однакове форматування для всього абзацу.

Як створити NSAttributedString в коді

Створення NSAttributedString виконується через ініціалізатор, що приймає рядок та словник атрибутів. Атрибути застосовуються до всього рядка. Для змішаного форматування (різні атрибути в різних частинах рядка) використовується NSMutableAttributedString з подальшим додаванням атрибутів до конкретних діапазонів. Objective-C використовує словник NSAttributedStringKey: UIFont, а Swift — типобезпечний словник [NSAttributedString.Key: Any].

swift
let plainText = "Hello, Swift!"

// Create with uniform attributes for the entire string
let attributes: [NSAttributedString.Key: Any] = [
    NSAttributedString.Key.font:
        UIFont.systemFont(ofSize: 18),
    NSAttributedString.Key.foregroundColor:
        UIColor.darkText,
    NSAttributedString.Key.kern: 1.5
]

let attributedString =
    NSAttributedString(string: plainText,
                        attributes: attributes)

Створення з NSMutableParagraphStyle

Приклад демонструє форматування абзацу через NSMutableParagraphStyle. Встановлюється вирівнювання по центру, міжрядковий інтервал 8 пунктів, відступ після абзацу 12 пунктів. ParagraphStyle додається до словника атрибутів під ключем .paragraphStyle. NSAttributedString копіює переданий paragraphStyle, тому після створення рядка його можна змінювати без впливу на вже створений рядок.

swift
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.center
paragraphStyle.lineSpacing = 8.0
paragraphStyle.paragraphSpacing = 12.0
paragraphStyle.firstLineHeadIndent = 20.0

let attributed = NSAttributedString(
    string: "Centered paragraph with spacing",
    attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])

NSMutableAttributedString та зміна атрибутів

NSMutableAttributedString — це підклас NSAttributedString, який дозволяє змінювати вміст та атрибути після створення. Основні методи: addAttribute(_:value:range:) для додавання одного атрибуту до діапазону; addAttributes(_:range:) для додавання кількох атрибутів; setAttributes(_:range:) для заміни всіх атрибутів у діапазоні; removeAttribute(_:range:) для видалення атрибуту; replaceCharacters(in:with:) для заміни тексту.

addAttribute та addAttributes додають атрибути до існуючих, не видаляючи вже задані. Якщо в діапазоні вже є атрибут з тим самим ключем, його значення замінюється. setAttributes повністю замінює словник атрибутів для діапазону — всі раніше задані атрибути видаляються. Це важливо розуміти при послідовному форматуванні одного рядка: addAttributes безпечніший, оскільки не скидає вже встановлені шрифти та кольори.

Діапазони (NSRange) задаються структурою NSRange(location: 0, length: 5). location — початковий індекс (0-базований), length — кількість символів. Якщо діапазон виходить за межі рядка, NSMutableAttributedString генерує виняток NSRangeException. Для безпечної роботи з діапазонами використовуються методи NSRange з Foundation, такі як NSIntersectionRange та NSUnionRange.

swift
let attributed = NSMutableAttributedString(
    string: "Bold and red text here")

// Apply bold font to first 9 characters
let boldRange = NSRange(location: 0, length: 9)
attributed.addAttribute(
    NSAttributedString.Key.font,
    value: UIFont.boldSystemFont(ofSize: 16),
    range: boldRange)

// Apply red color to characters 13-16 ("text")
let redRange = NSRange(location: 13, length: 4)
attributed.addAttribute(
    NSAttributedString.Key.foregroundColor,
    value: UIColor.red,
    range: redRange)

// Apply underline to the entire string
let fullRange = NSRange(location: 0,
                       length: attributed.length)
attributed.addAttribute(
    NSAttributedString.Key.underlineStyle,
    value: NSUnderlineStyle.single.rawValue,
    range: fullRange)

Приклад відображення атрибутованого рядка в UILabel

Найбільш поширений спосіб відображення NSAttributedString — присвоїти його властивості attributedText UILabel. На відміну від властивості text, attributedText використовує атрибути для рендерингу, підтримуючи змішане форматування. Важливо: якщо задано attributedText, UILabel ігнорує властивості font, textColor, textAlignment — усі візуальні характеристики беруться з атрибутів NSAttributedString.

swift
let label = UILabel()
label.numberOfLines = 0

let fullText = NSMutableAttributedString(
    string: "Price: $24.99 per month")

// Format "Price:" label with bold font
let priceLabelRange = NSRange(
    location: 0, length: 6)
fullText.addAttribute(
    NSAttributedString.Key.font,
    value: UIFont.boldSystemFont(ofSize: 16),
    range: priceLabelRange)

// Format "$24.99" with green color
let amountRange = NSRange(
    location: 7, length: 6)
fullText.addAttribute(
    NSAttributedString.Key.foregroundColor,
    value: UIColor.systemGreen(),
    range: amountRange)
fullText.addAttribute(
    NSAttributedString.Key.font,
    value: UIFont.boldSystemFont(ofSize: 22),
    range: amountRange)

// Apply gray color to "per month" text
let periodRange = NSRange(
    location: 14, length: 9)
fullText.addAttribute(
    NSAttributedString.Key.foregroundColor,
    value: UIColor.secondaryLabel,
    range: periodRange)

label.attributedText = fullText

Відображення в UITextView з інтерактивними посиланнями

UITextView підтримує інтерактивні посилання в NSAttributedString. Атрибут .link з NSURL робить текст клікабельним. Для обробки натискань використовується делегат UITextViewDelegate з методом textView(_:shouldInteractWith:in:interaction:). Також UITextView підтримує виділення тексту та використання UIMenuController для стандартних операцій (копіювання, пошук).

Конвертація NSAttributedString в HTML та RTF

NSAttributedString підтримує конвертацію з HTML та RTF через NSAttributedString.DocumentType. Для завантаження HTML використовується ініціалізатор з параметрами documentAttributes: NSAttributedString(data: htmlData, options: [.documentType: .html], documentAttributes: nil). Аналогічно для RTF: .rtf або .rtfd. Цей механізм корисний для відображення HTML-контенту без WebView.

Для експорту в HTML використовується метод data(from:documentAttributes:) з діапазоном та типом документа. Експорт HTML: try attributedString.data(from: fullRange, documentAttributes: [.documentType: .html]). Отримані дані можна зберегти у файл, відправити на сервер або відобразити в WebView. При експорті зберігаються шрифти, кольори, вирівнювання, списки — всі атрибути форматування конвертуються в CSS-стилі.

Підтримка RTF особливо актуальна для macOS-додатків, де RTF є стандартним форматом збагаченого тексту. iOS також підтримує читання та запис RTF, але не використовує його як основний формат. Різниця між RTF та RTFD: RTFD включає вкладені ресурси (зображення), упаковані в директорію-папку. NSAttributedString може обробляти обидва формати через єдиний інтерфейс.

swift
let htmlString = "<p><b>Bold<\/b> and <i>italic<\/i><\/p>"
guard let htmlData = htmlString.data(
    using: String.Encoding.utf8) else { return }

let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
    NSAttributedString.DocumentReadingOptionKey.documentType:
        NSAttributedString.DocumentType.html
]

let attributedFromHTML =
    try? NSAttributedString(
        data: htmlData,
        options: options,
        documentAttributes: nil)

Часті запитання

У чому різниця між NSString та NSAttributedString?

NSString зберігає лише послідовність символів Unicode без будь-якої інформації про форматування. NSAttributedString зберігає символи і для кожного піддіапазону містить словник атрибутів (шрифт, колір, стиль). При відображенні NSAttributedString UIKit використовує ці атрибути для рендерингу, створюючи форматований текст.

Чому UILabel не відображає атрибути NSAttributedString?

Найчастіша причина — використання властивості text замість attributedText. При присвоєнні через text всі атрибути ігноруються. Друга причина: після встановлення attributedText ви змінюєте font, textColor або textAlignment UILabel — ці зміни скидають attributedText. Використовуйте лише attributedText для форматованого тексту.

Як застосувати різні шрифти до одного рядка?

Створіть NSMutableAttributedString та викличте addAttribute(.font, value: boldFont, range: boldRange) для кожної ділянки з різним шрифтом. Кожен виклик застосовує атрибут лише до вказаного діапазону. Інші символи зберігають стандартний шрифт або інший заданий раніше. Таким чином створюються атрибутні runs з різними шрифтами.

Чи працює NSAttributedString з багаторядковим текстом?

Так, NSAttributedString коректно обробляє багаторядковий текст, включаючи символи нового рядка ( ). UITextView та UILabel (з numberOfLines = 0) автоматично переносять текст на новий рядок. NSMutableParagraphStyle керує міжрядковим інтервалом, відступами та вирівнюванням для кожного абзацу незалежно.

Як створити кольоровий текст з різними кольорами в одному рядку?

Використовуйте NSMutableAttributedString з атрибутом .foregroundColor для кожного кольорового діапазону. Для червоного тексту: addAttribute(.foregroundColor, value: UIColor.red, range: firstRange). Для синього: addAttribute(.foregroundColor, value: UIColor.blue, range: secondRange). Кольори будуть застосовані лише до вказаних діапазонів символів.

Підсумки

  • NSAttributedString — рядок з атрибутами форматування (шрифт, колір, стиль), що зберігаються в словнику для кожного діапазону символів
  • NSMutableAttributedString — змінна версія з методами addAttribute, setAttributes та removeAttribute для динамічного форматування
  • Основні атрибути: .font, .foregroundColor, .paragraphStyle, .kern, .underlineStyle, .strikethroughStyle, .link, .shadow, .baselineOffset
  • NSMutableParagraphStyle керує вирівнюванням, міжрядковим інтервалом, відступами та напрямком тексту для абзаців
  • UILabel, UITextView, UITextField підтримують відображення форматованого тексту через властивість attributedText
  • Конвертація HTML/RTF — NSAttributedString підтримує імпорт та експорт форматованого тексту через documentType

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також