NSAttributedString — to klasa z frameworku Foundation w iOS SDK, reprezentująca ciąg znaków z zestawem atrybutów formatowania stosowanych do pojedynczych znaków lub zakresów tekstu. W przeciwieństwie do zwykłego NSString, NSAttributedString przechowuje nie tylko znaki Unicode, ale także słownik atrybutów (czcionka, kolor, odstęp między znakami, wyrównanie) dla każdego segmentu ciągu. Według Apple Developer Documentation (2026), NSAttributedString stanowi podstawę do wyświetlania sformatowanego tekstu we wszystkich komponentach UI w iOS.
Najważniejsze
NSAttributedString — to fundamentalna klasa iOS/macOS do pracy z sformatowanym tekstem. Rozszerza możliwości NSString, dodając do ciągu atrybuty — słownik par klucz-wartość, gdzie klucz to stała NSAttributedStringKey (np. .font, .foregroundColor), a wartość to odpowiedni obiekt (UIFont, UIColor). Każdy znak w ciągu może mieć własny zestaw atrybutów, co pozwala zrealizować mieszane formatowanie w jednym ciągu.
Architektura NSAttributedString opiera się na koncepcji zakresów atrybutów (attribute runs). Jeśli ustawisz atrybut .font = UIFont.boldSystemFont(ofSize: 16) dla zakresu znaków 0..5, wszystkie znaki tego zakresu wyświetlą się pogrubioną czcionką. Pozostałe znaki mogą mieć inną czcionkę lub nie mieć atrybutu wcale. Podczas wyświetlania atrybutowanego ciągu system UIKit łączy cechy z różnych zakresów i renderuje tekst jednolicie.
NSAttributedString jest niezmienny — po utworzeniu jego atrybuty i zawartość nie mogą być zmienione. Do modyfikacji istnieje podklasa NSMutableAttributedString, która udostępnia metody dodawania, usuwania i zmiany atrybutów w dowolnych zakresach. Ta różnica jest istotna dla wielowątkowości: niezmienny NSAttributedString jest bezpieczny wątkowo, a NSMutableAttributedString — nie.
NSAttributedString obsługuje około 40 standardowych atrybutów zdefiniowanych w NSAttributedStringKey. Każdy atrybut wpływa na określony aspekt wyglądu tekstu: czcionkę, kolor, położenie, podkreślenie, cień, odstęp między znakami, styl akapitu i hiperłącza. Do ustawienia atrybutu używa się stałej NSAttributedStringKey, której przypisuje się obiekt odpowiedniego typu.
| Klucz atrybutu | Typ wartości | Przeznaczenie |
|---|---|---|
| .font | UIFont | Czcionka i rozmiar tekstu |
| .foregroundColor | UIColor | Kolor tekstu |
| .backgroundColor | UIColor | Kolor tła pod tekstem |
| .paragraphStyle | NSParagraphStyle | Wyrównanie, odstęp między wierszami, wcięcia |
| .kern | NSNumber (Float) | Odstęp między znakami (kerning) |
| .underlineStyle | NSUnderlineStyle (Int) | Styl podkreślenia (single, double, thick, pattern) |
| .strikethroughStyle | NSUnderlineStyle (Int) | Styl przekreślenia |
| .link | NSURL | URL dla interaktywnego hiperłącza |
| .shadow | NSShadow | Cień tekstu z offset, blurRadius i kolorem |
| .baselineOffset | NSNumber (Float) | Przesunięcie tekstu względem linii bazowej |
NSMutableParagraphStyle — obiekt zarządzający wizualnymi cechami akapitu: wyrównanie (.alignment: .left, .center, .right, .justified), odstęp między wierszami (.lineSpacing), odstęp między akapitami (.paragraphSpacing), wcięcie pierwszego wiersza (.firstLineHeadIndent), wcięcie lewe i prawe (.headIndent, .tailIndent) oraz kierunek tekstu (.baseWritingDirection). ParagraphStyle stosuje się do zakresu, który obejmuje znaki nowej linii, jeśli wymagane jest jednakowe formatowanie dla całego akapitu.
Tworzenie NSAttributedString odbywa się przez inicjalizator przyjmujący ciąg i słownik atrybutów. Atrybuty są stosowane do całego ciągu. Do mieszanego formatowania (różne atrybuty w różnych częściach ciągu) używa się NSMutableAttributedString z następnym dodawaniem atrybutów do konkretnych zakresów. Objective-C używa słownika NSAttributedStringKey: UIFont, a Swift — typowo bezpiecznego słownika [NSAttributedString.Key: Any].
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)
Przykład demonstruje formatowanie akapitu przez NSMutableParagraphStyle. Ustawiane jest wyrównanie do środka, odstęp między wierszami 8 punktów, odstęp po akapicie 12 punktów. ParagraphStyle jest dodawany do słownika atrybutów pod kluczem .paragraphStyle. NSAttributedString kopiuje przekazany paragraphStyle, więc po utworzeniu ciągu można go zmieniać bez wpływu na już utworzony ciąg.
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 — to podklasa NSAttributedString, która umożliwia zmianę zawartości i atrybutów po utworzeniu. Główne metody: addAttribute(_:value:range:) do dodania jednego atrybutu do zakresu; addAttributes(_:range:) do dodania wielu atrybutów; setAttributes(_:range:) do zastąpienia wszystkich atrybutów w zakresie; removeAttribute(_:range:) do usunięcia atrybutu; replaceCharacters(in:with:) do zastąpienia tekstu.
addAttribute i addAttributes dodają atrybuty do istniejących, nie usuwając już ustawionych. Jeśli w zakresie istnieje już atrybut z tym samym kluczem, jego wartość jest zastępowana. setAttributes całkowicie zastępuje słownik atrybutów dla zakresu — wszystkie wcześniej ustawione atrybuty są usuwane. To ważne przy sekwencyjnym formatowaniu jednego ciągu: addAttributes jest bezpieczniejszy, ponieważ nie resetuje już ustawionych czcionek i kolorów.
Zakresy (NSRange) są określane strukturą NSRange(location: 0, length: 5). location — indeks początkowy (0-bazowany), length — liczba znaków. Jeśli zakres wychodzi poza granice ciągu, NSMutableAttributedString generuje wyjątek NSRangeException. Do bezpiecznej pracy z zakresami używa się metod NSRange z Foundation, takich jak NSIntersectionRange i NSUnionRange.
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)
Najbardziej powszechny sposób wyświetlania NSAttributedString — przypisanie go do właściwości attributedText UILabel. W przeciwieństwie do właściwości text, attributedText używa atrybutów do renderowania, obsługując mieszane formatowanie. Ważne: jeśli ustawiono attributedText, UILabel ignoruje właściwości font, textColor, textAlignment — wszystkie cechy wizualne pochodzą z atrybutów NSAttributedString.
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 obsługuje interaktywne linki w NSAttributedString. Atrybut .link z NSURL sprawia, że tekst jest klikalny. Do obsługi kliknięć używa się delegata UITextViewDelegate z metodą textView(_:shouldInteractWith:in:interaction:). UITextView obsługuje również zaznaczanie tekstu i korzystanie z UIMenuController dla standardowych operacji (kopiowanie, wyszukiwanie).
NSAttributedString obsługuje konwersję z HTML i RTF przez NSAttributedString.DocumentType. Do załadowania HTML używa się inicjalizatora z parametrami documentAttributes: NSAttributedString(data: htmlData, options: [.documentType: .html], documentAttributes: nil). Analogicznie dla RTF: .rtf lub .rtfd. Ten mechanizm jest przydatny do wyświetlania treści HTML bez WebView.
Do eksportu do HTML używa się metody data(from:documentAttributes:) z zakresem i typem dokumentu. Export HTML: try attributedString.data(from: fullRange, documentAttributes: [.documentType: .html]). Otrzymane dane można zapisać do pliku, wysłać na serwer lub wyświetlić w WebView. Podczas eksportu zachowywane są czcionki, kolory, wyrównanie, listy — wszystkie atrybuty formatowania są konwertowane do stylów CSS.
Wsparcie dla RTF jest szczególnie istotne w aplikacjach macOS, gdzie RTF jest standardowym formatem tekstu sformatowanego. iOS również obsługuje odczyt i zapis RTF, ale nie używa go jako podstawowego formatu. Różnica między RTF a RTFD: RTFD zawiera zagnieżdżone zasoby (obrazy) spakowane w katalog. NSAttributedString może obsługiwać oba formaty przez jednolity interfejs.
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)
Często zadawane pytania
NSString przechowuje tylko sekwencję znaków Unicode bez żadnych informacji o formatowaniu. NSAttributedString przechowuje znaki i dla każdego podzakresu zawiera słownik atrybutów (czcionka, kolor, styl). Podczas wyświetlania NSAttributedString UIKit używa tych atrybutów do renderowania, tworząc sformatowany tekst.
Najczęstszą przyczyną jest użycie właściwości text zamiast attributedText. Przy przypisaniu przez text wszystkie atrybuty są ignorowane. Drugą przyczyną: po ustawieniu attributedText zmieniasz font, textColor lub textAlignment UILabel — te zmiany resetują attributedText. Używaj tylko attributedText dla sformatowanego tekstu.
Utwórz NSMutableAttributedString i wywołaj addAttribute(.font, value: boldFont, range: boldRange) dla każdego fragmentu z inną czcionką. Każde wywołanie stosuje atrybut tylko do określonego zakresu. Pozostałe znaki zachowują standardową czcionkę lub inną ustawioną wcześniej. W ten sposób tworzone są zakresy atrybutów (attribute runs) z różnymi czcionkami.
Tak, NSAttributedString poprawnie obsługuje tekst wieloliniowy, w tym znaki nowej linii ( ). UITextView i UILabel (z numberOfLines = 0) automatycznie przenoszą tekst do nowej linii. NSMutableParagraphStyle zarządza odstępem między wierszami, wcięciami i wyrównaniem dla każdego akapitu niezależnie.
Użyj NSMutableAttributedString z atrybutem .foregroundColor dla każdego zakresu kolorów. Dla czerwonego tekstu: addAttribute(.foregroundColor, value: UIColor.red, range: firstRange). Dla niebieskiego: addAttribute(.foregroundColor, value: UIColor.blue, range: secondRange). Kolory zostaną zastosowane tylko do określonych zakresów znaków.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również