NSTextAttachment UIKit फ्रेमवर्क की एक क्लास है जो NSAttributedString के माध्यम से फ़ॉर्मेट किए गए टेक्स्ट में इमेज और अन्य मीडिया ऑब्जेक्ट्स को एम्बेड करने की अनुमति देती है। यह TextKit और Core Text के स्तर पर काम करती है, जो डेवलपर्स को टेक्स्ट प्रवाह के भीतर अटैचमेंट के आकार, स्थिति और व्यवहार पर नियंत्रण देती है। Apple Documentation (2025) के अनुसार, NSTextAttachment इमेज, PDF और कस्टम व्यू कंटेनर को सपोर्ट करता है, जो UITextView और UILabel के साथ एकीकृत होता है। iOS ऐप्लिकेशन में Rich Text बनाने के लिए इस API को समझना आवश्यक है — चैट और एडिटर से लेकर कैप्शन में आइकन वाली न्यूज़ फ़ीड तक।
मुख्य बातें
NSTextAttachment UIKit फ्रेमवर्क की एक क्लास है जो मीडिया ऑब्जेक्ट्स को सीधे NSAttributedString की टेक्स्ट सामग्री में एम्बेड करने की अनुमति देती है। टेक्स्ट के बगल में रखे गए अलग UIImageView के विपरीत, NSTextAttachment इमेज को टेक्स्ट प्रवाह का हिस्सा बनाता है: इमेज लाइनों के साथ जाती है, संरेखण में भाग लेती है, और एक सामान्य वर्ण की तरह स्थान लेती है।
यह क्लास TextKit आर्किटेक्चर का हिस्सा है, जो iOS और macOS पर टेक्स्ट रेंडरिंग का प्रबंधन करती है। TextKit टेक्स्ट को ग्लिफ़ में तोड़ता है, कर्निंग, लिगेचर और लीडिंग को ध्यान में रखता है — और NSTextAttachment इस पाइपलाइन में एक विशेष वर्ण के रूप में फिट होता है जो एक अक्षर के रूप में नहीं बल्कि एक ग्राफिक ऑब्जेक्ट के रूप में रेंडर होता है।
प्रत्येक NSTextAttachment इंस्टेंस में contents (फ़ाइल डेटा), fileType (UTI सामग्री प्रकार), और bounds (पॉइंट्स में एक आयत जो आकार और स्थिति निर्धारित करता है) शामिल है। Apple Human Interface Guidelines के अनुसार, bounds डिफ़ॉल्ट रूप से इमेज आकार के बराबर होता है, लेकिन फ़ॉन्ट के साथ सटीक फ़िट के लिए बदला जा सकता है।
NSTextAttachment का उपयोग अलग UIImageView के बजाय करें जब इमेज को टेक्स्ट के हिस्से के रूप में व्यवहार करना चाहिए — चैट, न्यूज़ फ़ीड, टेक्स्ट एडिटर और इनपुट फ़ील्ड में आइकन वाले फ़ॉर्म में।
NSTextAttachment के साथ मूल कार्यप्रवाह तीन चरणों में होता है: एक इंस्टेंस बनाएँ, इमेज सेट करें, और इसे NSAttributedString से जोड़ें। आइए 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 एट्रिब्यूट में परिवर्तित हो जाता है, जो एक विशेष ऑब्जेक्ट रिप्लेसमेंट कैरेक्टर (कोड 0xFFFC) से जुड़ता है। यह वर्ण एक अक्षर के रूप में प्रदर्शित नहीं होता — इसके बजाय, image प्रॉपर्टी से इमेज उसके स्थान पर खींची जाती है।
यदि इमेज को टेक्स्ट लाइन के बीच में रखा जाना चाहिए (उदाहरण के लिए, एक शब्द के बाद आइकन), तो बस NSMutableAttributedString में वांछित स्थान पर attachmentString डालें। TextKit स्वचालित रूप से लाइन की ऊँचाई को ध्यान में रखेगा और इमेज को बेसलाइन पर संरेखित करेगा।
महत्वपूर्ण: image प्रॉपर्टी केवल iOS पर उपलब्ध है (iOS 7 से)। macOS पर, NSImage के साथ contents प्रॉपर्टी का उपयोग करें। पिछड़ी संगतता के लिए, डेटा कंटेनर पर निर्भर रहने के बजाय हमेशा सीधे image सेट करना पसंद करें।
डिफ़ॉल्ट रूप से, NSTextAttachment इमेज को पॉइंट्स में मूल आकार पर प्रदर्शित करता है। व्यवहार में, लगभग हमेशा आकार और वर्टिकल स्थिति को समायोजित करने की आवश्यकता होती है — यह bounds प्रॉपर्टी का उपयोग करके किया जाता है।
CGRect bounds संरचना में origin (X और Y द्वारा ऑफ़सेट) और size (चौड़ाई और ऊँचाई) शामिल है। Y ऑफ़सेट विशेष रूप से महत्वपूर्ण है: नकारात्मक मान इमेज को बेसलाइन से नीचे ले जाता है, सकारात्मक मान इसे ऊपर उठाता है। एक सामान्य परिदृश्य एक आइकन को टेक्स्ट लाइन के केंद्र में संरेखित करना है।
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 का उपयोग करती है — पूर्ण लाइन ऊँचाई नहीं, बल्कि एक बड़े अक्षर की ऊँचाई। यह सुनिश्चित करता है कि आइकन दृष्टिगत रूप से टेक्स्ट के शीर्ष किनारे से मेल खाता है, न कि बेसलाइन और एसेंडर के बीच तैरता है। उदाहरण में इमेज का आकार 18×18 pt है, जो UI टेक्स्ट में आइकन के लिए सामान्य है।
यदि इमेज टेक्स्ट लाइन से बड़ी होनी चाहिए (उदाहरण के लिए, चैट में फ़ोटो पूर्वावलोकन), TextKit स्वचालित रूप से वर्तमान लाइन के लिए लाइन स्पेसिंग बढ़ाएगा। इस मामले में, bounds को प्राकृतिक आकार पर सेट किया जाना चाहिए, और Y ऑफ़सेट शून्य पर।
NSTextAttachment न केवल PNG और JPEG बल्कि PDF दस्तावेज़ों के साथ-साथ contents प्रॉपर्टी के माध्यम से मनमानी फ़ाइलों का भी समर्थन करता है। यह इसे iOS ऐप्लिकेशन में Rich Text के लिए एक सार्वभौमिक उपकरण बनाता है।
attachment.image में PDF इमेज सेट करते समय, सिस्टम स्वचालित रूप से दस्तावेज़ का पहला पृष्ठ रेंडर करता है। हालाँकि, सटीक रेंडरिंग के लिए, डेटा और UTI प्रकार के साथ इनिशियलाइज़र के माध्यम से सीधे डेटा का उपयोग करें:
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 लौटाएँ और draw विधि में Core Graphics के माध्यम से ड्राइंग लागू करें।
NSTextAttachment UILabel और UITextView दोनों में सही ढंग से काम करता है। हालाँकि, UITextView अधिक क्षमताएँ प्रदान करता है: अटैचमेंट के साथ इंटरैक्शन (आइकन पर टैप करना), इमेज के साथ टेक्स्ट संपादित करना, और NSAttachmentBehavior के लिए समर्थन।
UITextView में NSTextAttachment पर टैप को संभालने के लिए, UITextViewDelegate प्रोटोकॉल और textView(_:shouldInteractWith:in:interaction:) विधि का उपयोग करें। यह विधि तब कॉल की जाती है जब उपयोगकर्ता किसी अटैचमेंट पर टैप करता है और स्क्रीन पर नेविगेट करने, पॉपअप खोलने या एनिमेशन चलाने की अनुमति देती है।
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 लौटाकर इसे अक्षम कर सकते हैं।
NSTextAttachment के साथ UITextView को संपादित करते समय, यह याद रखना महत्वपूर्ण है: रिप्लेसमेंट कैरेक्टर (0xFFFC) को हटाने से अटैचमेंट भी हट जाता है। उपयोगकर्ता इमेज को एक एकल तत्व के रूप में देखता है — इसे पूरे रूप में चुना जाता है, पिक्सेल दर पिक्सेल नहीं। iOS 15+ पर अटैचमेंट के ड्रैग-एंड-ड्रॉप समर्थन के लिए, NSTextAttachmentViewProvider का उपयोग करें।
पहली सामान्य गलती है bounds को अनदेखा करना. डेवलपर अक्सर मूल इमेज आकार पर निर्भर रहते हैं, जिससे टेक्स्ट में विशाल आइकन या, इसके विपरीत, बमुश्किल दिखाई देने वाली इमेज होती हैं। हमेशा फ़ॉन्ट और संदर्भ को ध्यान में रखते हुए bounds को स्पष्ट रूप से सेट करें।
दूसरी गलती है गलत Y ऑफ़सेट. bounds.origin.y में सकारात्मक मान इमेज को नीचे ले जाता है (UIKit के समन्वय प्रणाली में, Y अक्ष नीचे की ओर इंगित करता है — यह अतार्किक लगता है, लेकिन Core Graphics इसी तरह काम करता है)। एक लाइन के भीतर केंद्र-संरेखण के लिए, फ़ॉन्ट के capHeight के साथ सूत्र का उपयोग करें जैसा कि अनुभाग 3 में दिखाया गया है।
तीसरी समस्या है traitCollection बदलने पर इमेज का खो जाना. जब उपयोगकर्ता डार्क मोड या Dynamic Type स्विच करता है, तो फ़ॉन्ट का आकार बदल सकता है, लेकिन bounds वही रहता है। समाधान layoutSubviews विधि में या फ़ॉन्ट पर KVO के माध्यम से bounds की गणना गतिशील रूप से करना है।
चौथी बार-बार होने वाली गलती है numberOfLines > 1 के साथ UILabel में NSTextAttachment का उपयोग करना. सीमित चौड़ाई के साथ मल्टीलाइन मोड में, TextKit इमेज के साथ लाइनों को सही ढंग से रैप करता है। समस्या तब उत्पन्न होती है जब अटैचमेंट की ऊँचाई लाइन की ऊँचाई से अधिक हो जाती है — आसन्न लाइनें एक-दूसरे पर ओवरलैप होती हैं। समाधान NSMutableParagraphStyle के माध्यम से lineSpacing बढ़ाना है।
अक्सर पूछे जाने वाले प्रश्न
NSTextAttachment इमेज को टेक्स्ट प्रवाह का हिस्सा बनाता है: यह टेक्स्ट के साथ जाता है, संरेखित होता है और स्केल होता है। UIImageView सुपरव्यू निर्देशांक से बंधा होता है और टेक्स्ट लेआउट में भाग नहीं लेता।
हाँ, यदि आप text के बजाय attributedText प्रॉपर्टी सेट करते हैं। UILabel सही ढंग से NSTextAttachment प्रदर्शित करता है लेकिन इंटरैक्टिविटी का समर्थन नहीं करता। अटैचमेंट पर टैप के लिए, UITextView का उपयोग करें।
मौजूदा NSTextAttachment इंस्टेंस की bounds प्रॉपर्टी बदलें। नया NSAttributedString बनाने की आवश्यकता के बिना टेक्स्ट स्वचालित रूप से नए आकारों के साथ फिर से रेंडर होगा।
NSTextAttachment स्थिर इमेज का समर्थन करता है। GIF और एनिमेटेड प्रारूपों के लिए, iOS 15+ पर NSTextAttachmentViewProvider या CADisplayLink के माध्यम से कस्टम कार्यान्वयन की आवश्यकता है।
एक NSTextAttachment इंस्टेंस बनाएँ, इमेज या डेटा सेट करें, bounds सेट करें, इसे NSAttributedString(attachment:) में लपेटें, और insert(_:at:) विधि का उपयोग करके NSMutableAttributedString में डालें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें