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-а — слике унутар текста која се приказује као инлајн елемент. Ово се користи за креирање текста са иконицама, емоџијима или прилагођеним приказима унутар низа.
Сваки атрибут 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-а, mutabl верзија подржава измену садржаја без креирања новог објекта. Ово је кључно за уређиваче текста, ћаскања и форме, где корисник може да уређује текст, а стилови морају да се задрже.
У апликацијама за размену порука, свака порука садржи име корисника (подебљани фонт), текст поруке (обичан), време (сива боја). 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 прихвата атрибуте за placeholder и унети текст одвојено.
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-а је оправдана за прилагођене текстуалне распореде: колоне, обликовање око слика, ротацију текста, нестандардне преломе редова. 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 се приказује као обичан текст. При прослеђивању 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође