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 χωρίζει το κείμενο σε γλύφους, λαμβάνει υπόψη kerning, ligatures και διάστιχο, και το NSTextAttachment εντάσσεται σε αυτή τη γραμμή παραγωγής ως ένα ειδικό σύμβολο που αποδίδεται όχι ως γράμμα, αλλά ως γραφικό αντικείμενο.

Κάθε παράδειγμα NSTextAttachment περιέχει τις ιδιότητες contents (δεδομένα αρχείου), fileType (τύπος UTI περιεχομένου) και bounds (ορθογώνιο σε points που καθορίζει το μέγεθος και τη θέση). Σύμφωνα με το 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 εμφανίζει την εικόνα στο αρχικό της μέγεθος σε points. Στην πράξη σχεδόν πάντα απαιτείται προσαρμογή του μεγέθους και της κάθετης θέσης, γι αυτό χρησιμοποιείται η ιδιότητα 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:). Αυτή η μέθοδος καλείται όταν ο χρήστης πατάει το συνημμένο και επιτρέπει την πλοήγηση σε οθόνη, το άνοιγμα popup ή την αναπαραγωγή κινούμενων γραφικών.

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) διαγράφει και το συνημμένο. Ο χρήστης βλέπει την εικόνα ως ένα ενιαίο στοιχείο, επιλέγεται ολόκληρη, όχι pixel προς pixel. Για υποστήριξη μεταφοράς συνημμένων σε 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 είναι συνδεδεμένο με τις συντεταγμένες του superview και δεν συμμετέχει στη διάταξη κειμένου.

Μπορεί να προστεθεί 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης