NSTextAttachment, UIKit framework’ünden bir sınıftır ve NSAttributedString aracılığıyla biçimlendirilmiş metne resimler ve diğer medya nesneleri eklemeyi sağlar. TextKit ve Core Text düzeyinde çalışır ve geliştiricilere metin akışı içindeki eklerin boyutu, konumu ve davranışı üzerinde kontrol sağlar. Apple Documentation’a (2025) göre NSTextAttachment, resimleri, PDF’leri ve özel görünüm kaplarını destekler ve UITextView ile UILabel ile entegre olur. iOS uygulamalarında Zengin Metin (Rich Text) oluşturmak için bu API’yi anlamak gereklidir — sohbetlerden ve düzenleyicilerden, alt yazılarda simge bulunan haber akışlarına kadar.
Anahtar Noktalar
NSTextAttachment, UIKit framework’ünden bir sınıftır ve medya nesnelerini doğrudan NSAttributedString’in metin içeriğine eklemeyi sağlar. Metnin yanına yerleştirilen ayrı bir UIImageView’ın aksine, NSTextAttachment görüntüyü metin akışının bir parçası haline getirir: görüntü satırlarla birlikte sarılır, hizalamaya katılır ve normal bir karakter gibi yer kaplar.
Sınıf, iOS ve macOS’ta metin işlemesini yöneten TextKit mimarisinin bir parçasıdır. TextKit, metni gliflere ayırır, karakter aralığını, bitişik harfleri ve satır aralığını dikkate alır — ve NSTextAttachment bu ardışık hatta, bir harf olarak değil grafik bir nesne olarak işlenen özel bir karakter olarak yer alır.
Her NSTextAttachment örneği contents (dosya verileri), fileType (UTI içerik türü) ve bounds (boyut ve konumu tanımlayan nokta cinsinden bir dikdörtgen) içerir. Apple Human Interface Guidelines’a göre, bounds varsayılan olarak resim boyutundadır ancak yazı tipine hassas şekilde uyacak şekilde değiştirilebilir.
Görüntünün metnin bir parçası olarak davranması gerektiğinde (sohbetlerde, haber akışlarında, metin düzenleyicilerinde ve giriş alanlarında simge bulunan formlarda) ayrı bir UIImageView yerine NSTextAttachment kullanın.
NSTextAttachment ile temel iş akışı üç adımdan oluşur: bir örnek oluşturun, resmi ayarlayın ve NSAttributedString’e ekleyin. Süreci Swift kullanarak inceleyelim.
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ıktan sonra, NSTextAttachment nesnesi NSAttachmentAttributeName özniteliğine dönüştürülür ve özel bir nesne değiştirme karakterine (kod 0xFFFC) eklenir. Bu karakter bir harf olarak görüntülenmez — bunun yerine, image özelliğinden gelen resim onun yerine çizilir.
Görüntü bir metin satırının ortasına yerleştirilecekse (örneğin, bir kelimeden sonra simge), NSMutableAttributedString’de istenen konuma attachmentString’i eklemeniz yeterlidir. TextKit otomatik olarak satır yüksekliğini hesaba katacak ve görüntüyü taban çizgisine hizalayacaktır.
Önemli: image özelliği yalnızca iOS’ta kullanılabilir (iOS 7’den itibaren). macOS’ta, NSImage ile contents özelliğini kullanın. Geriye dönük uyumluluk için, her zaman veri kabına güvenmek yerine doğrudan image ayarlamayı tercih edin.
Varsayılan olarak, NSTextAttachment görüntüyü nokta cinsinden orijinal boyutunda görüntüler. Pratikte, boyutu ve dikey konumu neredeyse her zaman ayarlamak gerekir — bu, bounds özelliği kullanılarak yapılır.
CGRect bounds yapısı, origin (X ve Y cinsinden kayma) ve size (genişlik ve yükseklik) içerir. Y kayması özellikle önemlidir: negatif bir değer görüntüyü taban çizgisinin altına indirir, pozitif bir değer yukarı kaldırır. Tipik bir senaryo, bir simgeyi metin satırının ortasına hizalamaktır.
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
)
Hizalama hesaplaması, yazı tipinin capHeight değerini kullanır — tam satır yüksekliğini değil, büyük harf yüksekliğini. Bu, simgenin taban çizgisi ve çıkıntı arasında yüzmek yerine metnin üst kenarıyla görsel olarak eşleşmesini sağlar. Örnekteki görüntü boyutu 18×18 pt’dir ve bu, arayüz metnindeki simgeler için tipiktir.
Görüntü metin satırından daha büyükse (örneğin, bir sohbette fotoğraf önizlemesi), TextKit geçerli satır için satır aralığını otomatik olarak artıracaktır. Bu durumda, bounds doğal boyuta ve Y kayması sıfıra ayarlanmalıdır.
NSTextAttachment yalnızca PNG ve JPEG’i değil, aynı zamanda PDF belgelerini ve contents özelliği aracılığıyla isteğe bağlı dosyaları da destekler. Bu, onu iOS uygulamalarında Zengin Metin için evrensel bir araç haline getirir.
attachment.image’a bir PDF görüntüsü ayarlarken, sistem otomatik olarak belgenin ilk sayfasını işler. Ancak, hassas işleme için, veri ve UTI türüyle başlatıcı aracılığıyla doğrudan verileri kullanın:
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 parametresi bir UTI dizesi (Uniform Type Identifier) kabul eder. Standart türler şunları içerir: public.image (herhangi bir görüntü), public.jpeg, public.png, com.adobe.pdf. Doğru UTI belirtildiğinde, sistem uygun işleme yöntemini seçer — PDF için CGPDFDocument, görüntüler için CGImageSource.
Özel dosya türleri için (örneğin, SVG formatındaki vektör grafikleri), image(forBounds:textContainer:characterIndex:) yöntemini geçersiz kılan bir NSTextAttachment alt sınıfına ihtiyacınız olacaktır. Standart işleme uygun değilse, nil döndürün ve draw yönteminde Core Graphics aracılığıyla çizimi uygulayın.
NSTextAttachment hem UILabel hem de UITextView’de doğru çalışır. Ancak UITextView daha fazla yetenek sağlar: eklere dokunma (simgeye dokunma), görüntülerle birlikte metin düzenleme ve NSAttachmentBehavior desteği.
UITextView’de NSTextAttachment’a dokunmaları işlemek için UITextViewDelegate protokolünü ve textView(_:shouldInteractWith:in:interaction:) yöntemini kullanın. Bu yöntem, kullanıcı bir eke dokunduğunda çağrılır ve bir ekrana gitme, açılır pencere açma veya animasyon oynatma olanağı sağlar.
func textView(_ textView: UITextView,
shouldInteractWith attachment: NSTextAttachment,
in characterRange: NSRange,
interaction: UITextItemInteraction) -> Bool {
if interaction == .preview {
return false
}
// Detay ekranını aç
showImageDetail(attachment.image)
return false
}
Yöntem, interaction parametresi aracılığıyla etkileşim türlerini ayırt eder: .preview (3D Touch / Haptic Touch), .default (normal dokunma) ve .presentActions (bağlam menüsü). Her tür için kendi davranışınızı tanımlayabilir veya false döndürerek devre dışı bırakabilirsiniz.
NSTextAttachment ile UITextView düzenlerken şunu hatırlamak önemlidir: değiştirme karakterini (0xFFFC) silmek, eki de siler. Kullanıcı görüntüyü tek bir öğe olarak görür — piksel piksel değil, bir bütün olarak seçilir. iOS 15+’ta eklerin sürükle-bırak desteği için NSTextAttachmentViewProvider kullanın.
İlk yaygın hata bounds’u görmezden gelmektir. Geliştiriciler genellikle orijinal görüntü boyutuna güvenir ve bu da metinde devasa simgelere veya tam tersine neredeyse görünmeyen görüntülere yol açar. Yazı tipini ve bağlamı dikkate alarak her zaman bounds’u açıkça ayarlayın.
İkinci hata yanlış Y kaymasıdır. bounds.origin.y’deki pozitif bir değer görüntüyü aşağı indirir (UIKit’in koordinat sisteminde Y ekseni aşağıyı gösterir — bu sezgisel görünmeyebilir, ancak Core Graphics böyle çalışır). Bir satır içinde ortalamak için, Bölüm 3’te gösterildiği gibi yazı tipinin capHeight değeriyle formülü kullanın.
Üçüncü sorun traitCollection değişiminde görüntü kaybıdır. Kullanıcı Karanlık Mod veya Dynamic Type’a geçtiğinde, yazı tipi boyutu değişebilir ancak bounds aynı kalır. Çözüm, layoutSubviews yönteminde veya font üzerinde KVO aracılığıyla bounds’u dinamik olarak hesaplamaktır.
Dördüncü sık yapılan hata, numberOfLines > 1 olan UILabel’da NSTextAttachment kullanmaktır. Sınırlı genişlikte çok satırlı modda, TextKit görüntüyle birlikte satırları doğru şekilde kaydırır. Sorun, ek yüksekliği satır yüksekliğini aştığında ortaya çıkar — bitişik satırlar birbiriyle örtüşür. Çözüm, NSMutableParagraphStyle aracılığıyla lineSpacing’i artırmaktır.
Sık Sorulan Sorular
NSTextAttachment görüntüyü metin akışının bir parçası yapar: metinle birlikte sarılır, hizalanır ve ölçeklenir. UIImageView, üst görünüm koordinatlarına bağlıdır ve metin düzenine katılmaz.
Evet, text yerine attributedText özelliğini ayarlarsanız. UILabel, NSTextAttachment’ı doğru şekilde görüntüler ancak etkileşimi desteklemez. Eke dokunmalar için UITextView kullanın.
Mevcut NSTextAttachment örneğinin bounds özelliğini değiştirin. Yeni bir NSAttributedString oluşturmaya gerek kalmadan metin otomatik olarak yeni boyutlarla yeniden işlenir.
NSTextAttachment statik görüntüleri destekler. GIF ve animasyonlu formatlar için, iOS 15+’ta NSTextAttachmentViewProvider veya CADisplayLink aracılığıyla özel bir uygulama gereklidir.
Bir NSTextAttachment örneği oluşturun, görüntüyü veya verileri ayarlayın, bounds’u belirleyin, NSAttributedString(attachment:) içine sarın ve insert(_:at:) yöntemini kullanarak NSMutableAttributedString’e ekleyin.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun