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 — простая строка символов без стилевой информации. Любой текст, переданный в UILabel через text, отображается одним шрифтом, цветом и размером. NSAttributedString, переданный через attributedText, позволяет каждому символу иметь собственный набор атрибутов. 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 — изображение внутри текста, которое отображается как inline-элемент. Это используется для создания текстов с иконками, эмодзи или кастомными вьюхами внутри строки.
Каждый атрибут 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.
Создание NSAttributedString в Swift выполняется через инициализатор с указанием текста и словаря атрибутов, либо через 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, mutable-версия поддерживает изменение содержимого без создания нового объекта. Это критично для текстовых редакторов, чатов и форм, где пользователь может редактировать текст, а стили должны сохраняться.
В мессенджерах каждое сообщение содержит имя пользователя (жирный шрифт), текст сообщения (обычный), время (серый цвет). 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
Результат — одна строка с тремя стилевыми участками. Append корректно вычисляет NSRange автоматически, позиции не нужно рассчитывать вручную. Такой подход масштабируется на любое количество фрагментов.
Метод enumerateAttributes(in:options:using:) проходит по всем диапазонам атрибутов в указанном интервале. Это полезно для анализа форматирования: найти все ссылки, изменить цвет определённых атрибутов или экспортировать текст в HTML. В замыкание передаются словарь атрибутов и NSRange текущего участка.
Все основные UI-компоненты для отображения текста в UIKit поддерживают NSAttributedString через свойство attributedText. 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 — низкоуровневый фреймворк Apple для рендеринга текста, который работает напрямую с NSAttributedString. В отличие от UIKit, Core Text не использует NSAttributedString напрямую как отображаемый объект, а преобразует его в CTFramesetter, затем CTFrame и рендерит в Core Graphics контексте. Это даёт полный контроль над расстановкой строк и глифов.
Использование Core Text оправдано для кастомных текстовых layout: колонки, обтекание изображений, вращение текста, нестандартные разрывы строк. NSMutableParagraphStyle Core Text включает атрибуты, которых нет в UIKit: kCTParagraphStyleSpecifierMaximumLineSpacing, kCTParagraphStyleSpecifierLineBreakMode с дополнительными режимами.
NSAttributedString бесперебойно передаётся между UIKit и Core Text, так как оба фреймворка работают с одним типом. Атрибуты UIKit (NSFontAttributeName, NSForegroundColorAttributeName) автоматически распознаются Core Text, и наоборот — атрибуты Core Text (kCTFontAttributeName) читаются UIKit. Это позволяет использовать UIKit для простых задач и Core Text для кастомного рендеринга на одном объекте NSAttributedString.
Часто задаваемые вопросы
NSString хранит только текст без стилевой информации. NSAttributedString дополняет текст словарём атрибутов для каждого диапазона символов. При передаче в UILabel через свойство text NSString отображается plain text. При передаче NSAttributedString через свойство attributedText применяются все атрибуты: разные шрифты, цвета и интервалы в одной строке.
Используйте метод addAttributes(_:range:) с словарём атрибутов: addAttributes([.font: font, .foregroundColor: color], range: range). Для добавления или изменения одного атрибута используйте addAttribute(_:value:range:). Метод setAttributes заменяет все существующие атрибуты в диапазоне на переданные.
Создайте NSMutableParagraphStyle, установите свойство lineSpacing, затем передайте его как значение атрибута NSParagraphStyleAttributeName. Для полного контроля доступны также minimumLineHeight, maximumLineHeight, paragraphSpacing, lineBreakMode и alignment. ParagraphStyle — единственный способ управления межстрочным интервалом.
Да, SwiftUI поддерживает NSAttributedString через Text(attributedString:) в iOS 15+. В более старых версиях используйте UIViewRepresentable с UILabel или UITextView. SwiftUI также предоставляет собственный тип AttributedString (SwiftUI, не Foundation) для декларативного форматирования с Markdown-подобным синтаксисом.
Используйте метод boundingRect(with:options:context:), который возвращает CGRect, необходимый для отображения строки с заданными атрибутами. Параметр options: [.usesLineFragmentOrigin, .usesFontLeading] учитывает межстрочные интервалы и шрифтовые метрики. Для UILabel с ограниченным количеством строк используйте sizeThatFits.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также