NSTextAttachment — UIKit freymvorkundan olan sinifdir, NSAttributedString vasitəsilə formatlaşdırılmış mətnə şəkillər və digər media obyektləri yerləşdirməyə imkan verir. TextKit və Core Text səviyyəsində işləyir, tərtibatçılara mətn axını daxilində əlavələrin ölçüsü, mövqeyi və davranışı üzərində nəzarət verir. Apple Documentation-a (2025) görə, NSTextAttachment şəkilləri, PDF-i və fərdi görünüş konteynerlərini dəstəkləyir, UITextView və UILabel ilə inteqrasiya olunur. Bu API-ni başa düşmək iOS tətbiqlərində Rich Text yaratmaq üçün lazımdır — söhbətlərdən və redaktorlardan tutmuş, imzalarda ikonları olan xəbər lentlərinə qədər.
Əsas məqamlar
NSTextAttachment — UIKit freymvorkundan olan sinifdir, NSAttributedString-in mətn məzmununa birbaşa media obyektləri yerləşdirməyə imkan verir. Mətnin yanında yerləşən ayrıca UIImageView-dən fərqli olaraq, NSTextAttachment şəkli mətn axınının bir hissəsi edir: şəkil sətirlərlə birlikdə daşınır, düzləşdirmədə iştirak edir və adi simvol kimi yer tutur.
Sinif iOS və macOS-da mətnin render edilməsini idarə edən TextKit arxitekturasının bir hissəsidir. TextKit mətni gliflərə bölür, kerning, liqatura və interlinyanı nəzərə alır — və NSTextAttachment bu konveyerə hərf kimi deyil, qrafik obyekt kimi render olunan xüsusi simvol kimi qoşulur.
Hər bir NSTextAttachment nümunəsi contents (fayl məlumatları), fileType (UTI məzmun növü) və bounds (ölçü və mövqeyi təyin edən nöqtələrdə düzbucaqlı) xassələrini ehtiva edir. Apple Human Interface Guidelines-a görə, bounds susmaya görə şəklin ölçüsünə bərabərdir, lakin şriftə dəqiq uyğunlaşdırmaq üçün dəyişdirilə bilər.
NSTextAttachment-dən ayrıca UIImageView əvəzinə, şəkil mətnin bir hissəsi kimi davranmalı olduqda istifadə edin — söhbətlərdə, xəbər lentlərində, mətn redaktorlarında və giriş sahələrində ikonları olan formalarda.
NSTextAttachment ilə işin əsas ssenarisi üç addımdan ibarətdir: nümunə yaratmaq, şəkli təyin etmək və NSAttributedString-ə əlavə etmək. Prosesi Swift nümunəsində nəzərdən keçirək.
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:) çağırıldıqdan sonra NSTextAttachment obyekti NSAttachmentAttributeName atributuna çevrilir, bu da xüsusi əvəzedici simvola (object replacement character, kod 0xFFFC) əlavə olunur. Bu simvol hərf kimi göstərilmir — onun əvəzinə image xassəsindən şəkil çəkilir.
Şəkil mətn sətirinin ortasında yerləşməlidirsə (məsələn, sözdən sonra ikona), sadəcə attachmentString-i NSMutableAttributedString-in lazımi mövqeyinə daxil edin. TextKit avtomatik olaraq sətrin hündürlüyünü nəzərə alacaq və şəkli baza xətti üzrə düzləşdirəcək.
Vacib: image xassəsi yalnız iOS-da (iOS 7-dən başlayaraq) mövcuddur. macOS-da NSImage ilə contents xassəsindən istifadə edin. Geriyə uyğunluq üçün həmişə image-i birbaşa təyin edin, data konteynerinə güvənməyin.
Susmaya görə NSTextAttachment şəkli onun orijinal ölçüsündə nöqtələrlə göstərir. Təcrübədə demək olar həmişə ölçü və şaquli mövqeyi düzəltmək tələb olunur — bunun üçün bounds xassəsindən istifadə edilir.
CGRect bounds strukturu origin (X və Y üzrə yerdəyişmə) və size (en və hündürlük) daxildir. Y üzrə yerdəyişmə xüsusilə vacibdir: mənfi dəyər şəkli baza xəttindən aşağı salır, müsbət dəyər yuxarı qaldırır. Tipik ssenari — ikonanı mətn sətirinin mərkəzinə düzləşdirmək.
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
)
Düzləşdirmənin hesablanması şriftin capHeight-dən istifadə edir — sətrin tam hündürlüyü deyil, böyük hərfin hündürlüyü. Bu, ikonanın vizual olaraq mətnin yuxarı sərhəddi ilə üst-üstə düşməsini təmin edir, baseline və ascender arasında sallanmır. Nümunədə şəklin ölçüsü 18×18 pt-dir, bu UI mətnində ikonlar üçün tipikdir.
Şəkil mətn sətirindən böyük olmalıdırsa (məsələn, söhbətdə foto önizləməsi), TextKit cari sətir üçün sətirlərarası intervalı avtomatik artıracaq. Bu halda bounds təbii ölçüdə təyin edilir, Y üzrə yerdəyişmə isə sıfır.
NSTextAttachment təkcə PNG və JPEG deyil, həm də PDF sənədlərini və contents xassəsi vasitəsilə ixtiyari faylları dəstəkləyir. Bu, onu iOS tətbiqlərində Rich Text üçün universal alət edir.
attachment.image-də PDF şəkli təyin edərkən sistem avtomatik olaraq sənədin ilk səhifəsini render edir. Lakin dəqiq göstərmək üçün data və UTI növü ilə birbaşa inicilizatordan istifadə edin:
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 parametri UTI sətri (Uniform Type Identifier) qəbul edir. Standart növlər: public.image (istənilən şəkil), public.jpeg, public.png, com.adobe.pdf. Düzgün UTI göstərildikdə sistem düzgün render üsulunu seçir — PDF üçün bu CGPDFDocument, şəkillər üçün CGImageSource-dur.
Fərdi fayl növləri üçün (məsələn, SVG formatında vektor qrafikası) NSTextAttachment alt sinfi tələb olunacaq, image(forBounds:textContainer:characterIndex:) metodunu ləğv edən. Standart render uyğun deyilsə, nil qaytarın və draw metodunda Core Graphics vasitəsilə çəkməni tətbiq edin.
NSTextAttachment həm UILabel-də, həm də UITextView-də düzgün işləyir. Lakin UITextView daha çox imkan verir: əlavələrlə qarşılıqlı əlaqə (ikonaya toxunma), şəkillərlə birlikdə mətnin redaktəsi və NSAttachmentBehavior dəstəyi.
UITextView-də NSTextAttachment-a toxunmanı idarə etmək üçün UITextViewDelegate delegatı və textView(_:shouldInteractWith:in:interaction:) metodu istifadə olunur. Bu metod istifadəçi əlavəyə toxunduqda çağırılır və ekrana keçməyə, popup açmağa və ya animasiya oynatmağa imkan verir.
func textView(_ textView: UITextView,
shouldInteractWith attachment: NSTextAttachment,
in characterRange: NSRange,
interaction: UITextItemInteraction) -> Bool {
if interaction == .preview {
return false
}
// Ətraflı ekranı aç
showImageDetail(attachment.image)
return false
}
Metod qarşılıqlı əlaqə növlərini interaction parametri vasitəsilə fərqləndirir: .preview (3D Touch / Haptic Touch), .default (adi toxunma) və .presentActions (kontekst menyu). Hər bir növ üçün öz davranışını təyin edə və ya false qaytararaq qadağan edə bilərsiniz.
NSTextAttachment ilə UITextView redaktə edərkən vacibdir: əvəzedici simvolun (0xFFFC) silinməsi əlavəni də silir. İstifadəçi şəkli vahid element kimi görür — o, bütövlükdə seçilir, piksel-piksel yox. iOS 15+-də əlavələrin sürüklənməsini dəstəkləmək üçün NSTextAttachmentViewProvider-dən istifadə edin.
Birinci geniş yayılmış səhv — bounds-a məhəl qoymamaq. Tərtibatçılar tez-tez şəklin orijinal ölçüsünə güvənirlər, bu da mətndə nəhəng ikonalara və ya əksinə, çətin görünən şəkillərə gətirib çıxarır. Həmişə bounds-i şrift və konteksti nəzərə alaraq açıq şəkildə təyin edin.
İkinci səhv — Y üzrə səhv yerdəyişmə. bounds.origin.y-də müsbət dəyər şəkli aşağı salır (UIKit koordinat sistemində Y oxu aşağı yönəlib — bu məntiqsiz görünür, lakin Core Graphics belə işləyir). Sətrin mərkəzinə düzləşdirmək üçün 3-cü bölmədə göstərildiyi kimi şriftin capHeight düsturundan istifadə edin.
Üçüncü problem — traitCollection dəyişikliyində şəklin itirilməsi. İstifadəçi Dark Mode və ya Dynamic Type dəyişdirdikdə şriftin ölçüsü dəyişə bilər, bounds isə əvvəlki kimi qalır. Həll — bounds-i layoutSubviews metodunda və ya font-da KVO vasitəsilə dinamik hesablamaq.
Dördüncü tez-tez rast gəlinən səhv — UILabel-də numberOfLines > 1 ilə NSTextAttachment istifadəsi. Çoxsətirli rejimdə və məhdud enlə TextKit sətirləri şəkillə birlikdə düzgün şəkildə köçürür. Problem attachment hündürlüyü sətrin hündürlüyünü aşdıqda yaranır — qonşu sətirlər üst-üstə düşür. Həll — NSMutableParagraphStyle vasitəsilə lineSpacing-i artırmaq.
Tez-tez verilən suallar
NSTextAttachment şəkli mətn axınının bir hissəsi edir: o, mətnlə birlikdə daşınır, düzləşdirilir və miqyaslanır. UIImageView superview-in koordinatlarına bağlıdır və mətnin düzümündə iştirak etmir.
Bəli, əgər text əvəzinə attributedText xassəsini təyin etsəniz. UILabel NSTextAttachment-i düzgün göstərir, lakin interaktivliyi dəstəkləmir. Əlavəyə toxunmaq üçün UITextView-dən istifadə edin.
Mövcud NSTextAttachment nümunəsinin bounds xassəsini dəyişdirin. Mətn avtomatik olaraq yeni ölçülərlə yenidən render olunacaq, yeni NSAttributedString yaratmağa ehtiyac yoxdur.
NSTextAttachment statik şəkilləri dəstəkləyir. GIF və animasiyalı formatlar üçün iOS 15+-də NSTextAttachmentViewProvider və ya CADisplayLink vasitəsilə fərdi tətbiq tələb olunacaq.
NSTextAttachment nümunəsi yaradın, image və ya data təyin edin, bounds təyin edin, NSAttributedString(attachment:) ilə sarın və insert(_:at:) metodu vasitəsilə NSMutableAttributedString-ə daxil edin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun