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)Стиль подчёркивания (single, double, thick, pattern)
.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:) с диапазоном и типом документа. HTMLEXport: 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 корректно обрабатывает многострочный текст, включая символы новой строки (\n). 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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