NSTextAttachment: шта је то и како додати слику у текст на iOS-у

Аутор: IT Sectr Објављено: 2026-07-25 Време читања: 9 мин

NSTextAttachment је класа из UIKit оквира која омогућава уграђивање слика и других медијских објеката у форматирани текст кроз NSAttributedString. Ради на нивоу TextKit-а и Core Text-а, дајући програмерима контролу над величином, позицијом и понашањем прилога унутар тока текста. Према Apple Documentation (2025), NSTextAttachment подржава слике, PDF и прилагођене контејнере приказа, интегришући се са UITextView и UILabel. Разумевање овог API-ја је неопходно за креирање Rich Text-а у iOS апликацијама — од четова и уређивача до феедова вести са иконицама у потписима.

Главно

  • NSTextAttachment — UIKit класа за уграђивање медија у форматирани iOS текст.
  • Слика се додаје кроз NSAttributedString са кључем NSAttachmentAttributeName.
  • Својство bounds управља величином и вертикалним померањем прилога.
  • NSTextAttachment подржава слике, PDF и прилагођене датотеке кроз контејнер података.
  • API се интегрише са UITextView, UILabel и TextKit-ом за флексибилан распоред текста.

Шта је NSTextAttachment?

NSTextAttachment је класа из UIKit оквира која омогућава уграђивање медијских објеката директно у садржај текста NSAttributedString-а. За разлику од одвојеног UIImageView-а постављеног поред текста, NSTextAttachment чини слику делом тока текста: слика се преноси заједно са редовима, учествује у поравнању и заузима место као обичан знак.

Класа је део TextKit архитектуре која управља приказивањем текста на iOS и macOS. TextKit дели текст на глифове, узима у обзир кернинг, лигатуре и интерлинијаж — а NSTextAttachment се уграђује у овај ток као посебан знак који се приказује не као слово, већ као графички објекат.

Свака инстанца NSTextAttachment садржи својства contents (подаци датотеке), fileType (UTI тип садржаја) и bounds (правоугаоник у поенима који одређује величину и положај). Према Apple Human Interface Guidelines, bounds подразумевано је једнак величини слике, али се може променити за прецизно прилагођавање фонту.

Користи NSTextAttachment уместо одвојеног UIImageView-а када слика треба да се понаша као део текста — у четовима, феедовима вести, уређивачима текста и обрасцима са иконицама у пољима за унос.

Како додати слику у текст кроз NSTextAttachment

Основни сценариј рада са NSTextAttachment састоји се од три корака: креирати инстанцу, поставити слику и прикачити на NSAttributedString. Размотримо процес на примеру Swift-а.

swift
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "icon-star")

let attachmentString = NSAttributedString(attachment: attachment)

let text = NSMutableAttributedString(string: "Rating: ")
text.append(attachmentString)

let label = UILabel()
label.attributedText = text

Након позива NSAttributedString(attachment:), објекат NSTextAttachment се претвара у атрибут NSAttachmentAttributeName који се прикачује на посебан знак замене (object replacement character, код 0xFFFC). Овај знак се не приказује као слово — уместо њега се црта слика из својства image.

Ако слика треба да се налази у средини реда текста (на пример, иконица после речи), једноставно убаци attachmentString на жељену позицију у NSMutableAttributedString. TextKit ће аутоматски узети у обзир висину реда и поравнати слику на базну линију.

Важно: својство image је доступно само на iOS-у (почев од iOS 7). На macOS-у користи својство contents са NSImage. За уназад компатибилност увек постављај image директно, не ослањај се на контејнер података.

Подешавање bounds и позиције прилога

Подразумевано, NSTextAttachment приказује слику у њеној оригиналној величини у поенима. У пракси скоро увек је потребно кориговати величину и вертикални положај — за то се користи својство bounds.

Структура CGRect bounds укључује origin (померање по X и Y) и size (ширина и висина). Померање по Y је посебно важно: негативна вредност спушта слику испод базне линије, позитивна је подиже. Типичан сценариј — поравнати иконицу на центар реда текста.

swift
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "icon-star")

let font = UIFont.systemFont(ofSize: 16)
let fontCapHeight = font.capHeight
let imageSize = CGSize(width: 18, height: 18)

attachment.bounds = CGRect(
    x: 0,
    y: (fontCapHeight - imageSize.height) / 2,
    width: imageSize.width,
    height: imageSize.height
)

Израчунавање поравнања користи capHeight фонту — висину великог слова, а не укупну висину реда. Ово гарантује да се иконица визуелно поклапа са горњом границом текста, а не да виси између baseline и ascender-а. Величина слике у примеру је 18×18 pt, што је типично за иконице у UI тексту.

Ако слика треба да буде већа од реда текста (на пример, преглед фотографије у чету), TextKit ће аутоматски повећати размак између редова за текући ред. У овом случају bounds се поставља у природној величини, а померање по Y — нула.

PDF и прилагођени прилози

NSTextAttachment подржава не само PNG и JPEG, већ и PDF документе, као и произвољне датотеке кроз својство contents. То га чини универзалним алатом за Rich Text у iOS апликацијама.

При постављању PDF слике у attachment.image, систем аутоматски приказује прву страницу документа. Међутим, за прецизно приказивање користи податке директно кроз иницијализатор са data и UTI типом:

swift
guard let pdfData = Bundle.main.url(forResource: "document",
                                  withExtension: "pdf") else { return }

let fileData = Data(contentsOf: pdfData)
let attachment = NSTextAttachment(data: fileData,
                                       ofType: "com.adobe.pdf")

attachment.bounds = CGRect(x: 0, y: -4,
                           width: 24, height: 24)

let pdfString = NSAttributedString(attachment: attachment)

Параметар ofType прима UTI стринг (Uniform Type Identifier). Стандардни типови: public.image (било која слика), public.jpeg, public.png, com.adobe.pdf. При навођењу исправног UTI-ја, систем бира одговарајући начин приказивања — за PDF је то CGPDFDocument, за слике — CGImageSource.

За прилагођене типове датотека (нпр. векторска графика у SVG формату) биће потребна поткласа NSTextAttachment-а која преписује метод image(forBounds:textContainer:characterIndex:). Ако стандардно приказивање није одговарајуће, врати nil и имплементирај цртање кроз Core Graphics у методи draw.

NSTextAttachment у UITextView и делегирање

NSTextAttachment исправно ради како у UILabel-у, тако и у UITextView-у. Међутим, UITextView пружа више могућности: интеракцију са прилозима (додир на иконицу), уређивање текста заједно са сликама и подршку за NSAttachmentBehavior.

За обраду додира на NSTextAttachment у UITextView-у користи се делегат UITextViewDelegate и метод textView(_:shouldInteractWith:in:interaction:). Овај метод се позива када корисник додирне прилог и омогућава прелазак на екран, отварање попапа или репродукцију анимације.

swift
func textView(_ textView: UITextView,
                shouldInteractWith attachment: NSTextAttachment,
                in characterRange: NSRange,
                interaction: UITextItemInteraction) -> Bool {
    if interaction == .preview {
        return false
    }
    // Отвори екран са детаљима
    showImageDetail(attachment.image)
    return false
}

Метод разликује типове интеракције кроз параметар interaction: .preview (3D Touch / Haptic Touch), .default (обичан додир) и .presentActions (контекстни мени). За сваки тип можеш поставити сопствено понашање или га забранити враћањем false.

При уређивању UITextView-а са NSTextAttachment-ом важно је запамтити: уклањање знака замене (0xFFFC) уклања и прилог. Корисник види слику као јединствени елемент — она се означава у целини, не пиксел по пиксел. За подршку превлачења прилога у iOS 15+ користи NSTextAttachmentViewProvider.

Типичне грешке при раду са NSTextAttachment

Прва честа грешка — игнорисање bounds. Програмери се често ослањају на оригиналну величину слике, што доводи до огромних иконица у тексту или, обрнуто, до слика које су једва видљиве. Увек постављај bounds експлицитно узимајући у обзир фонт и контекст.

Друга грешка — неправилно померање по Y. Позитивна вредност у bounds.origin.y спушта слику (у UIKit координатном систему Y оса је усмерена наниже — делује нелогично, али тако ради Core Graphics). За поравнање на центар реда користи формулу са capHeight фонту, као што је приказано у одељку 3.

Трећи проблем — губитак слике при промени traitCollection. Када корисник пребаци Dark Mode или Dynamic Type, величина фонту се може променити, а bounds остаје исти. Решење — израчунавати bounds динамички у методи layoutSubviews или кроз KVO на font.

Четврта честа грешка — коришћење NSTextAttachment у UILabel-у са numberOfLines > 1. У вишредном режиму и ограниченој ширини, TextKit исправно преноси редове заједно са сликом. Проблем настаје када висина прилога премашује висину реда — суседни редови се преклапају. Решење — повећати lineSpacing кроз NSMutableParagraphStyle.

Често постављана питања

Чим се NSTextAttachment разликује од UIImageView у тексту?

NSTextAttachment чини слику делом тока текста: она се преноси, поравнава и скалира заједно са текстом. UIImageView је везан за координате супервиев-а и не учествује у распореду текста.

Може ли се NSTextAttachment додати у UILabel?

Да, ако поставиш својство attributedText уместо text. UILabel исправно приказује NSTextAttachment, али не подржава интерактивност. За додир прилога користи UITextView.

Како променити величину слике након креирања attachment-а?

Промени својство bounds постојеће инстанце NSTextAttachment-а. Текст ће се аутоматски прорендеровати са новим величинама без потребе за креирањем новог NSAttributedString-а.

Да ли NSTextAttachment подржава анимиране слике?

NSTextAttachment подржава статичке слике. За GIF и анимиране формате биће потребна прилагођена имплементација кроз NSTextAttachmentViewProvider на iOS 15+ или кроз CADisplayLink.

Како додати NSTextAttachment у текст програмски?

Креирај инстанцу NSTextAttachment, постави image или data, подеси bounds, умотај у NSAttributedString(attachment:) и убаци у NSMutableAttributedString кроз метод insert(_:at:).

Закључак

  • NSTextAttachment — UIKit класа за уграђивање слика, PDF-ова и других медија у форматирани текст.
  • Слика се додаје кроз NSAttributedString(attachment:) и постаје део тока текста.
  • Својство bounds управља величином и позицијом: увек га постављај експлицитно узимајући у обзир фонт.
  • За поравнање иконице на центар реда користи формулу са capHeight текућег фонту.
  • PDF прилози су подржани кроз иницијализатор са data и исправним UTI типом.
  • За обраду додира прилога користи UITextViewDelegate и метод shouldInteractWith.
  • При промени Dynamic Type прерачунавај bounds динамички да би избегао преклапање редова.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође