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 за модификация на атрибути по време на изпълнение
  • Основни атрибути: .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 е thread-safe, докато 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:) с диапазон и тип документ. 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) за всяка част с различен шрифт. Всяко извикване прилага атрибута само към посочения диапазон. Останалите символи запазват стандартния шрифт или друг предварително зададен шрифт. По този начин се създават атрибутни диапазони (attribute 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също