NSTextAttachment: mi ez és hogyan adjunk képet szöveghez iOS-en

Szerző: IT Sectr Megjelenés: 2026-07-25 Olvasási idő: 9 perc

Az NSTextAttachment egy osztály az UIKit keretrendszerből, amely lehetővé teszi képek és más médiaobjektumok beágyazását formázott szövegbe a NSAttributedString segítségével. A TextKit és Core Text szintjén működik, így a fejlesztők irányítást kapnak a mellékletek mérete, pozíciója és viselkedése felett a szövegfolyamban. Az Apple Documentation (2025) szerint az NSTextAttachment támogatja a képeket, PDF-eket és egyedi nézetkonténereket, integrálva az UITextView-val és az UILabel-lel. Ennek az API-nak a megértése elengedhetetlen a Rich Text létrehozásához iOS-alkalmazásokban, a csevegőktől és szerkesztőktől a hírfolyamokig, amelyek ikonokat tartalmaznak a feliratokban.

Főbb pontok

  • NSTextAttachment — UIKit osztály média beágyazásához formázott iOS szövegbe.
  • Kép hozzáadása NSAttributedString segítségével az NSAttachmentAttributeName kulccsal.
  • A bounds tulajdonság vezérli a melléklet méretét és függőleges eltolását.
  • Az NSTextAttachment támogatja a képeket, PDF-eket és egyedi fájlokat adatkonténeren keresztül.
  • Az API integrálódik UITextView-val, UILabel-lel és TextKit-tel a rugalmas szövegelrendezéshez.

Mi az NSTextAttachment?

NSTextAttachment egy osztály az UIKit keretrendszerből, amely lehetővé teszi médiaobjektumok közvetlen beágyazását az NSAttributedString szöveges tartalmába. Ellentétben egy külön UIImageView-val, amely a szöveg mellé van helyezve, az NSTextAttachment a képet a szövegfolyam részévé teszi: a kép együtt mozog a sorokkal, részt vesz az igazításban, és helyet foglal, mint egy közönséges karakter.

Az osztály a TextKit architektúra része, amely a szöveg megjelenítését kezeli iOS-en és macOS-en. A TextKit glifekre bontja a szöveget, figyelembe véve a kerninget, ligatúrákat és sorközt, az NSTextAttachment pedig speciális karakterként csatlakozik ehhez a csővezetékhez, amely nem betűként, hanem grafikus objektumként jelenik meg.

Minden NSTextAttachment példány tartalmazza a contents (fájladatok), fileType (UTI tartalomtípus) és bounds (téglalap pontokban, amely meghatározza a méretet és pozíciót) tulajdonságokat. Az Apple Human Interface Guidelines szerint a bounds alapértelmezés szerint megegyezik a kép méretével, de módosítható a betűtípushoz való pontos illeszkedés érdekében.

Használja az NSTextAttachment-et külön UIImageView helyett, amikor a képnek a szöveg részeként kell viselkednie, csevegőkben, hírfolyamokban, szövegszerkesztőkben és ikonokat tartalmazó űrlapok beviteli mezőiben.

Kép hozzáadása szöveghez NSTextAttachment segítségével

Az NSTextAttachment-tel való munka alapszkriptuma három lépésből áll: példány létrehozása, kép beállítása és csatolás az NSAttributedString-hez. Vizsgáljuk meg a folyamatot egy Swift példán keresztül.

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

A NSAttributedString(attachment:) meghívása után az NSTextAttachment objektum NSAttachmentAttributeName attribútummá alakul, amely egy speciális helyettesítő karakterhez (object replacement character, kód 0xFFFC) csatolódik. Ez a karakter nem jelenik meg betűként, helyette az image tulajdonságból származó kép rajzolódik ki.

Ha a képnek egy szövegsor közepén kell elhelyezkednie (például ikon egy szó után), egyszerűen illessze be az attachmentString-et a kívánt pozícióba az NSMutableAttributedString-ben. A TextKit automatikusan figyelembe veszi a sor magasságát és az alapvonalra igazítja a képet.

Fontos: az image tulajdonság csak iOS-en érhető el (iOS 7-től kezdve). macOS-en használja a contents tulajdonságot NSImage-sel. A visszafelé kompatibilitás érdekében mindig közvetlenül állítsa be az image-t, ne hagyatkozzon az adatkonténerre.

A bounds és a melléklet pozíciójának beállítása

Alapértelmezés szerint az NSTextAttachment a képet az eredeti méretében jeleníti meg pontokban. A gyakorlatban szinte mindig szükség van a méret és a függőleges pozíció módosítására, ehhez a bounds tulajdonságot használjuk.

A CGRect bounds struktúra tartalmazza az origin-t (eltolás X és Y irányban) és a size-t (szélesség és magasság). Az Y irányú eltolás különösen fontos: a negatív érték a képet az alapvonal alá helyezi, a pozitív érték fölé emeli. Tipikus forgatókönyv — egy ikon középre igazítása egy szövegsorban.

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
)

Az igazítás kiszámítása a betűtípus capHeight értékét használja, a nagybetű magasságát, nem a teljes sormagasságot. Ez garantálja, hogy az ikon vizuálisan egybeessen a szöveg felső határával, ne lógjon az alapvonal és az ascender között. A kép mérete a példában 18×18 pt, ami tipikus az UI szövegben lévő ikonoknál.

Ha a képnek nagyobbnak kell lennie, mint a szövegsor (például fénykép előnézete egy csevegőben), a TextKit automatikusan megnöveli a sorközt az aktuális sorhoz. Ebben az esetben a bounds természetes méretre van állítva, az Y eltolás pedig nulla.

PDF és egyedi mellékletek

Az NSTextAttachment nem csak PNG és JPEG formátumokat támogat, hanem PDF dokumentumokat és tetszőleges fájlokat is a contents tulajdonságon keresztül. Ez univerzális eszközzé teszi a Rich Text számára iOS alkalmazásokban.

PDF kép beállításakor a attachment.image tulajdonságban a rendszer automatikusan megjeleníti a dokumentum első oldalát. A pontos megjelenítés érdekében azonban közvetlenül használja az adatokat az adatokat és UTI típust használó inicializátoron keresztül:

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)

Az ofType paraméter egy UTI stringet (Uniform Type Identifier) fogad. Szabványos típusok: public.image (bármely kép), public.jpeg, public.png, com.adobe.pdf. A helyes UTI megadásakor a rendszer kiválasztja a megfelelő megjelenítési módot, PDF esetén ez a CGPDFDocument, képek esetén a CGImageSource.

Egyedi fájltípusokhoz (pl. vektorgrafika SVG formátumban) az NSTextAttachment alosztályára lesz szükség, amely felülírja az image(forBounds:textContainer:characterIndex:) metódust. Ha a szabványos megjelenítés nem megfelelő, adjon vissza nil-t, és valósítsa meg a rajzolást a Core Graphics segítségével a draw metódusban.

NSTextAttachment UITextView-ban és delegálás

Az NSTextAttachment mind UILabel-ben, mind UITextView-ban helyesen működik. Az UITextView azonban több lehetőséget kínál: interakció a mellékletekkel (ikonra koppintás), szöveg szerkesztése képekkel együtt, és NSAttachmentBehavior támogatás.

Az NSTextAttachment-ra való koppintás kezeléséhez UITextView-ban a UITextViewDelegate delegáltat és a textView(_:shouldInteractWith:in:interaction:) metódust használjuk. Ez a metódus akkor hívódik meg, amikor a felhasználó megérinti a mellékletet, és lehetővé teszi a navigációt egy képernyőre, felugró ablak megnyitását vagy animáció lejátszását.

swift
func textView(_ textView: UITextView,
                shouldInteractWith attachment: NSTextAttachment,
                in characterRange: NSRange,
                interaction: UITextItemInteraction) -> Bool {
    if interaction == .preview {
        return false
    }
    // Részletek képernyő megnyitása
    showImageDetail(attachment.image)
    return false
}

A metódus az interakció típusait az interaction paraméteren keresztül különbözteti meg: .preview (3D Touch / Haptic Touch), .default (normál koppintás) és .presentActions (kontextusmenü). Minden típushoz beállíthat saját viselkedést, vagy letilthatja azt a false visszaadásával.

Az NSTextAttachment-tel rendelkező UITextView szerkesztésekor fontos megjegyezni: a helyettesítő karakter (0xFFFC) törlése a mellékletet is eltávolítja. A felhasználó a képet egyetlen egységként látja, az egészében van kijelölve, nem pixelről pixelre. A mellékletek húzásának támogatásához iOS 15+ használja az NSTextAttachmentViewProvider-t.

Gyakori hibák az NSTextAttachment használatakor

Az első gyakori hiba — a bounds figyelmen kívül hagyása. A fejlesztők gyakran hagyatkoznak a kép eredeti méretére, ami óriási ikonokhoz vezet a szövegben, vagy éppen ellenkezőleg, alig látható képekhez. Mindig állítsa be explicit módon a bounds-t, figyelembe véve a betűtípust és a kontextust.

A második hiba — helytelen Y eltolás. A pozitív érték a bounds.origin.y-ben lejjebb helyezi a képet (az UIKit koordinátarendszerben az Y tengely lefelé mutat, ez logikátlannak tűnik, de a Core Graphics így működik). A sor közepére igazításhoz használja a betűtípus capHeight képletét, ahogy a 3. szakaszban bemutattuk.

A harmadik probléma — a kép elvesztése a traitCollection megváltozásakor. Amikor a felhasználó Dark Mode vagy Dynamic Type módot vált, a betűméret megváltozhat, miközben a bounds változatlan marad. Megoldás — számítsa ki a bounds-t dinamikusan a layoutSubviews metódusban vagy KVO-n keresztül a font tulajdonságon.

A negyedik gyakori hiba — az NSTextAttachment használata UILabel-ben numberOfLines > 1 esetén. Többsoros módban és korlátozott szélesség mellett a TextKit helyesen viszi át a sorokat a képpel együtt. A probléma akkor merül fel, amikor a melléklet magassága meghaladja a sor magasságát, a szomszédos sorok átfedik egymást. Megoldás — növelje a lineSpacing értékét az NSMutableParagraphStyle segítségével.

Gyakran ismételt kérdések

Miben különbözik az NSTextAttachment az UIImageView-tól a szövegben?

NSTextAttachment a képet a szövegfolyam részévé teszi: együtt mozog a szöveggel, igazodik és méreteződik. Az UIImageView a szuperview koordinátáihoz van kötve, és nem vesz részt a szöveg elrendezésében.

Hozzáadható az NSTextAttachment az UILabel-hez?

Igen, ha a text helyett az attributedText tulajdonságot állítja be. Az UILabel helyesen jeleníti meg az NSTextAttachment-et, de nem támogatja az interaktivitást. A mellékletre való koppintáshoz használja az UITextView-t.

Hogyan változtatható meg a kép mérete az attachment létrehozása után?

Módosítsa a meglévő NSTextAttachment példány bounds tulajdonságát. A szöveg automatikusan újramegjelenik az új méretekkel, anélkül hogy új NSAttributedString-et kellene létrehozni.

Támogatja az NSTextAttachment az animált képeket?

NSTextAttachment statikus képeket támogat. GIF és animált formátumokhoz egyedi megvalósításra lesz szükség az NSTextAttachmentViewProvider segítségével iOS 15+ vagy CADisplayLink használatával.

Hogyan adható hozzá NSTextAttachment programozottan a szöveghez?

Hozzon létre egy NSTextAttachment példányt, állítsa be az image vagy data tulajdonságot, adja meg a bounds-t, csomagolja be NSAttributedString(attachment:)-be, és illessze be az NSMutableAttributedString-be az insert(_:at:) metódus segítségével.

Összefoglalás

  • NSTextAttachment — UIKit osztály képek, PDF-ek és más médiák formázott szövegbe ágyazásához.
  • A kép NSAttributedString(attachment:) segítségével kerül hozzáadásra, és a szövegfolyam részévé válik.
  • A bounds tulajdonság vezérli a méretet és pozíciót, mindig explicit módon állítsa be a betűtípus figyelembevételével.
  • Az ikon sor közepére igazításához használja az aktuális betűtípus capHeight képletét.
  • A PDF mellékletek a data és helyes UTI típusú inicializátoron keresztül támogatottak.
  • A mellékletre való koppintás kezeléséhez használja a UITextViewDelegate-et és a shouldInteractWith metódust.
  • Dynamic Type váltáskor számítsa újra a bounds-t dinamikusan a sorok átfedésének elkerülése érdekében.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is