NSAttributedString — este o clasă din framework-ul Foundation din iOS SDK, care reprezintă un șir cu un set de atribute de formatare aplicate caracterelor individuale sau intervalelor de text. Spre deosebire de NSString obișnuit, NSAttributedString stochează nu numai caractere Unicode, ci și un dicționar de atribute (font, culoare, spațiere între caractere, aliniere) pentru fiecare segment al șirului. Conform Apple Developer Documentation (2026), NSAttributedString este baza pentru afișarea textului formatat în toate componentele UI din iOS.
Principalele puncte
NSAttributedString — este o clasă fundamentală iOS/macOS pentru lucrul cu text formatat. Extinde capacitățile NSString, adăugând la șir atribute — un dicționar de perechi cheie-valoare, unde cheia este o constantă NSAttributedStringKey (de exemplu, .font, .foregroundColor), iar valoarea este obiectul corespunzător (UIFont, UIColor). Fiecare caracter din șir poate avea propriul set de atribute, permițând formatarea mixtă într-un singur șir.
Arhitectura NSAttributedString se bazează pe conceptul de intervale de atribute (attribute runs). Dacă setați atributul .font = UIFont.boldSystemFont(ofSize: 16) pentru intervalul de caractere 0..5, toate caracterele din acest interval se vor afișa cu font bold. Celelalte caractere pot avea un alt font sau pot să nu aibă deloc atribut. La afișarea unui șir cu atribute, sistemul UIKit combină caracteristicile din diferite intervale și redă textul uniform.
NSAttributedString este imutabil — după creare, atributele și conținutul său nu pot fi modificate. Pentru modificare există subclasa NSMutableAttributedString, care oferă metode pentru adăugarea, ștergerea și modificarea atributelor în orice interval. Această diferență este importantă pentru multi-threading: NSAttributedString imutabil este thread-safe, iar NSMutableAttributedString — nu.
NSAttributedString acceptă aproximativ 40 de atribute standard definite în NSAttributedStringKey. Fiecare atribut influențează un aspect specific al aspectului textului: font, culoare, poziție, subliniere, umbră, spațiere între caractere, stilul paragrafului și hiperlinkuri. Pentru a seta un atribut, se folosește constanta NSAttributedStringKey, căreia i se atribuie un obiect de tipul corespunzător.
| Cheia atributului | Tipul valorii | Destinație |
|---|---|---|
| .font | UIFont | Fontul și dimensiunea textului |
| .foregroundColor | UIColor | Culoarea textului |
| .backgroundColor | UIColor | Culoarea fundalului sub text |
| .paragraphStyle | NSParagraphStyle | Aliniere, spațiere între linii, indentări |
| .kern | NSNumber (Float) | Spațierea între caractere (kerning) |
| .underlineStyle | NSUnderlineStyle (Int) | Stilul sublinierei (single, double, thick, pattern) |
| .strikethroughStyle | NSUnderlineStyle (Int) | Stilul tăierii |
| .link | NSURL | URL pentru hiperlink interactiv |
| .shadow | NSShadow | Umbra textului cu offset, blurRadius și culoare |
| .baselineOffset | NSNumber (Float) | Deplasarea textului față de linia de bază |
NSMutableParagraphStyle — obiect care gestionează caracteristicile vizuale ale paragrafului: aliniere (.alignment: .left, .center, .right, .justified), spațiere între linii (.lineSpacing), distanța între paragrafe (.paragraphSpacing), indentarea primului rând (.firstLineHeadIndent), indentarea stângă și dreaptă (.headIndent, .tailIndent) și direcția textului (.baseWritingDirection). ParagraphStyle se aplică intervalului care include caracterele de nouă linie, dacă se dorește aceeași formatare pentru întregul paragraf.
Crearea NSAttributedString se realizează printr-un inițializator care primește un șir și un dicționar de atribute. Atributele se aplică întregului șir. Pentru formatarea mixtă (atribute diferite în părți diferite ale șirului) se folosește NSMutableAttributedString cu adăugarea ulterioară a atributelor la intervale specifice. Objective-C folosește dicționarul NSAttributedStringKey: UIFont, iar Swift — dicționarul type-safe [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)
Exemplul demonstrează formatarea paragrafului prin NSMutableParagraphStyle. Se setează alinierea la centru, spațierea între linii de 8 puncte, distanța după paragraf de 12 puncte. ParagraphStyle se adaugă în dicționarul de atribute sub cheia .paragraphStyle. NSAttributedString copiază paragraphStyle-ul transmis, deci după crearea șirului acesta poate fi modificat fără a afecta șirul deja creat.
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 — este o subclasă a NSAttributedString care permite modificarea conținutului și atributelor după creare. Metode principale: addAttribute(_:value:range:) pentru adăugarea unui atribut la un interval; addAttributes(_:range:) pentru adăugarea mai multor atribute; setAttributes(_:range:) pentru înlocuirea tuturor atributelor dintr-un interval; removeAttribute(_:range:) pentru ștergerea unui atribut; replaceCharacters(in:with:) pentru înlocuirea textului.
addAttribute și addAttributes adaugă atribute la cele existente, fără a le elimina pe cele deja setate. Dacă în interval există deja un atribut cu aceeași cheie, valoarea sa este înlocuită. setAttributes înlocuiește complet dicționarul de atribute pentru interval — toate atributele setate anterior sunt eliminate. Acest lucru este important la formatarea secvențială a unui singur șir: addAttributes este mai sigur, deoarece nu resetează fonturile și culorile deja setate.
Intervalele (NSRange) sunt definite prin structura NSRange(location: 0, length: 5). location — indicele de start (bazat pe 0), length — numărul de caractere. Dacă intervalul depășește limitele șirului, NSMutableAttributedString generează excepția NSRangeException. Pentru lucrul sigur cu intervalele se folosesc metodele NSRange din Foundation, cum ar fi 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)
Cea mai comună metodă de afișare a NSAttributedString — atribuirea sa proprietății attributedText a UILabel. Spre deosebire de proprietatea text, attributedText folosește atributele pentru randare, suportând formatarea mixtă. Important: dacă attributedText este setat, UILabel ignoră proprietățile font, textColor, textAlignment — toate caracteristicile vizuale provin din atributele 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 acceptă linkuri interactive în NSAttributedString. Atributul .link cu NSURL face textul clickabil. Pentru gestionarea clickurilor se folosește delegatul UITextViewDelegate cu metoda textView(_:shouldInteractWith:in:interaction:). UITextView acceptă și selectarea textului și utilizarea UIMenuController pentru operațiuni standard (copiere, căutare).
NSAttributedString acceptă conversia din HTML și RTF prin NSAttributedString.DocumentType. Pentru încărcarea HTML se folosește inițializatorul cu parametrii documentAttributes: NSAttributedString(data: htmlData, options: [.documentType: .html], documentAttributes: nil). La fel pentru RTF: .rtf sau .rtfd. Acest mecanism este util pentru afișarea conținutului HTML fără WebView.
Pentru exportul în HTML se folosește metoda data(from:documentAttributes:) cu intervalul și tipul documentului. Export HTML: try attributedString.data(from: fullRange, documentAttributes: [.documentType: .html]). Datele obținute pot fi salvate în fișier, trimise pe server sau afișate în WebView. La export se păstrează fonturile, culorile, alinierea, listele — toate atributele de formatare sunt convertite în stiluri CSS.
Suportul pentru RTF este deosebit de relevant pentru aplicațiile macOS, unde RTF este formatul standard al textului îmbogățit. iOS acceptă și el citirea și scrierea RTF, dar nu îl folosește ca format principal. Diferența dintre RTF și RTFD: RTFD include resurse imbricate (imagini) împachetate într-un director. NSAttributedString poate procesa ambele formate printr-o interfață unitară.
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)
Întrebări frecvente
NSString stochează doar o secvență de caractere Unicode fără nicio informație de formatare. NSAttributedString stochează caracterele și pentru fiecare subinterval conține un dicționar de atribute (font, culoare, stil). La afișarea NSAttributedString, UIKit folosește aceste atribute pentru randare, creând text formatat.
Cea mai frecventă cauză — utilizarea proprietății text în loc de attributedText. La atribuirea prin text, toate atributele sunt ignorate. A doua cauză: după setarea attributedText, modificați font, textColor sau textAlignment ale UILabel — aceste modificări resetează attributedText. Utilizați doar attributedText pentru text formatat.
Creați un NSMutableAttributedString și apelați addAttribute(.font, value: boldFont, range: boldRange) pentru fiecare porțiune cu font diferit. Fiecare apel aplică atributul doar intervalului specificat. Celelalte caractere păstrează fontul standard sau un alt font setat anterior. Astfel se creează intervale de atribute (attribute runs) cu fonturi diferite.
Da, NSAttributedString procesează corect textul pe mai multe linii, inclusiv caracterele de linie nouă ( ). UITextView și UILabel (cu numberOfLines = 0) transferă automat textul pe linie nouă. NSMutableParagraphStyle gestionează spațierea între linii, indentările și alinierea pentru fiecare paragraf independent.
Utilizați NSMutableAttributedString cu atributul .foregroundColor pentru fiecare interval de culoare. Pentru text roșu: addAttribute(.foregroundColor, value: UIColor.red, range: firstRange). Pentru albastru: addAttribute(.foregroundColor, value: UIColor.blue, range: secondRange). Culorile se vor aplica doar intervalelor de caractere specificate.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și