2013-05-03 11 views
39

मेरे पास एक कस्टम UIView के लिए गोलाकार कोनों और टेक्स्ट पृष्ठभूमि रंग के बारे में एक प्रश्न है।NSAttributedString पृष्ठभूमि रंग और गोलाकार कोनों

मूल रूप से, मैं इस तरह एक प्रभाव को प्राप्त करने की जरूरत है (छवि संलग्न - एक तरफ गोलाकार कोनों नोटिस) एक कस्टम UIView में: Background highlight

मैं उपयोग करने के लिए दृष्टिकोण सोच रहा हूँ है:

  • ग्लिफ रन प्राप्त करने के लिए कोर टेक्स्ट का उपयोग करें।
  • हाइलाइट रेंज की जांच करें।
  • यदि वर्तमान रन हाइलाइट रेंज के भीतर है, तो ग्लिफ रन ड्राइंग करने से पहले गोलाकार कोनों के साथ पृष्ठभूमि आयताकार बनाएं और इच्छित रंग भरें।
  • ग्लाइफ रन ड्रा करें।

हालांकि, मुझे यकीन नहीं है कि यह एकमात्र समाधान है (या उस मामले के लिए, चाहे यह सबसे कुशल समाधान है)।

UIWebView का उपयोग करना एक विकल्प नहीं है, इसलिए मुझे इसे कस्टम UIView में करना है।

मेरा प्रश्न यह है कि यह उपयोग करने का सबसे अच्छा तरीका है, और क्या मैं सही रास्ते पर हूं? या क्या मैं कुछ महत्वपूर्ण याद कर रहा हूं या गलत तरीके से जा रहा हूं?

+0

हैलो। आपके कमेंट के लिए धन्यवाद। :) मुझे नहीं लगता कि NSLayoutManager आईओएस 6 में उपलब्ध है। आईओएस 6 में सीटीफ्रेम सैटर है, जो मुझे सीटीफ़्रेम -> सीटीलाइन -> सीटीजीलीफ देगा। अगर मुझे आवश्यक पाठ की सीमा सही ढंग से मिलती है, तो मैं आयताकार पेंट कर सकता हूं और फिर सीटीफ़्रेम को स्वयं खींचने के लिए कह सकता हूं। – codeBearer

+0

क्षमा करें, हाँ। हो सकता है कि टेक्स्ट व्यू-> चयनित रेंज और '- [UITextInput selectRectsForRange:] ' – nielsbot

+0

क्या आप कोशिश कर सकते हैं? 1. लेबल पारदर्शी बनाएं 2. सबस्ट्रिंग टेक्स्ट रेंज का फ्रेम प्राप्त करें (http://stackoverflow.com/questions/19417776/how-do-i-locate-the-cgrect-for-a-substring-of -text-in-a-uilabel) 3. लेबल – Robert

उत्तर

47

मैं उपर्युक्त प्रभाव प्राप्त करने में कामयाब रहा, इसलिए सोचा कि मैं इसके लिए उत्तर पोस्ट करूंगा।

अगर किसी को इसे और अधिक प्रभावी बनाने के बारे में कोई सुझाव है, तो कृपया योगदान देने में संकोच न करें। मैं आपके उत्तर को सही के रूप में चिह्नित करना सुनिश्चित करूंगा। :)

ऐसा करने के लिए, आपको NSAttributedString पर "कस्टम विशेषता" जोड़ने की आवश्यकता होगी।

असल में, इसका मतलब यह है कि आप किसी भी कुंजी-मूल्य जोड़ी को जोड़ सकते हैं, जब तक कि यह ऐसा कुछ है जिसे आप NSDictionary उदाहरण में जोड़ सकते हैं। अगर सिस्टम उस विशेषता को नहीं पहचानता है, तो यह कुछ भी नहीं करता है। डेवलपर के रूप में, उस विशेषता के लिए एक कस्टम कार्यान्वयन और व्यवहार प्रदान करना आपके ऊपर निर्भर है।

इस उत्तर के प्रयोजनों के लिए, मान लीजिए कि मैंने [UIColor greenColor] के मूल्य के साथ @"MyRoundedBackgroundColor" नामक एक कस्टम विशेषता जोड़ा है।

अनुसरण करने वाले चरणों के लिए, आपको CoreText की सामग्री के बारे में मूलभूत समझ की आवश्यकता होगी। समझने के लिए एक फ्रेम/लाइन/ग्लिफ़ रन/ग्लिफ़ क्या, आदि

के लिए Apple's Core Text Programming Guide की जाँच करें तो, यहाँ कदम हैं:

  1. एक कस्टम UIView उपवर्ग बनाएँ।
  2. NSAttributedString को स्वीकार करने के लिए एक संपत्ति है।
  3. NSAttributedString उदाहरण का उपयोग कर CTFramesetter बनाएं।
  4. drawRect: विधि
  5. ओवरराइड CTFramesetter से एक CTFrame उदाहरण बनाएँ।
    1. बनाने के लिए आपको CGPathRef देने की आवश्यकता होगी। उस CGPath को उस फ्रेम के समान बनाएं जिसमें आप टेक्स्ट खींचना चाहते हैं।
  6. वर्तमान ग्राफिक्स संदर्भ प्राप्त करें और टेक्स्ट समन्वय प्रणाली को फ़्लिप करें।
  7. CTFrameGetLines(...) का उपयोग करके, CTFrame में सभी लाइनें प्राप्त करें जिन्हें आपने अभी बनाया है।
  8. CTFrameGetLineOrigins(...) का उपयोग करके, CTFrame के लिए सभी लाइन मूल प्राप्त करें।
  9. एक for loop शुरू
  10. - CTLine की सरणी में प्रत्येक पंक्ति के लिए ...
  11. CGContextSetTextPosition(...) का उपयोग कर CTLine की शुरुआत करने के लिए पाठ स्थिति निर्धारित करें।
  12. CTLineGetGlyphRuns(...) का उपयोग CTLine से सभी ग्लाइफ रन (CTRunRef) प्राप्त करें। CTRun की सरणी में प्रत्येक glyphRun के लिए ...
  13. CTRunGetStringRange(...) का उपयोग कर रन की सीमा प्राप्त करें -
  14. एक और for loop शुरू करो।
  15. CTRunGetTypographicBounds(...) का उपयोग कर टाइपोग्राफ़िक सीमाएं प्राप्त करें।
  16. CTLineGetOffsetForStringIndex(...) का उपयोग कर रन के लिए एक्स ऑफ़सेट प्राप्त करें।
  17. उपरोक्त कार्यों से लौटाए गए मानों का उपयोग करके बाउंडिंग रेक्ट की गणना करें (चलो इसे runBounds पर कॉल करें)।
    1. याद रखें - CTRunGetTypographicBounds(...) टेक्स्ट के "चढ़ाई" और "मूल" को स्टोर करने के लिए चर के लिए पॉइंटर्स की आवश्यकता है। रन ऊंचाई प्राप्त करने के लिए आपको उन्हें जोड़ने की आवश्यकता है।
  18. CTRunGetAttributes(...) का उपयोग कर रन के लिए गुण प्राप्त करें।
  19. जांचें कि विशेषता शब्दकोश में आपकी विशेषता है या नहीं।
  20. यदि आपकी विशेषता मौजूद है, तो आयत की सीमाओं की गणना करें जिन्हें चित्रित करने की आवश्यकता है।
  21. कोर टेक्स्ट की आधार रेखा पर मूल उत्पत्ति है। हमें पाठ के निम्नतम बिंदु से शीर्षतम बिंदु तक आकर्षित करने की आवश्यकता है। इस प्रकार, हमें वंश के लिए समायोजित करने की आवश्यकता है।
  22. तो, चरण 16 (runBounds) में गणना की गई बाध्यकारी आय से मूल को घटाएं।
  23. अब हमारे पास runBounds है, हम जानते हैं कि हम किस क्षेत्र को पेंट करना चाहते हैं - अब हम विशिष्ट गोलाकार कोनों के साथ एक रेक्ट खींचने और भरने के लिए CoreGraphis/UIBezierPath विधियों का उपयोग कर सकते हैं।
    1. UIBezierPath में bezierPathWithRoundedRect:byRoundingCorners:cornerRadii: नामक एक सुविधा वर्ग विधि है जो आपको विशिष्ट कोनों को गोल करने देती है। आप दूसरे पैरामीटर में बिट मास्क का उपयोग करके कोनों को निर्दिष्ट करते हैं।
  24. अब आपने रेक्ट भर लिया है, बस CTRunDraw(...) का उपयोग करके ग्लाइफ रन खींचें।
  25. अपनी कस्टम विशेषता बनाने के लिए जीत का जश्न मनाएं - एक बियर या कुछ पीएं!: डी

यह पता लगाने के संबंध में कि विशेषता सीमा कई रनों तक फैली हुई है, तो आप पहली बार जब आपके रन को गुणों का सामना करते हैं तो आप अपनी कस्टम विशेषता की पूरी प्रभावी सीमा प्राप्त कर सकते हैं। यदि आपको लगता है कि आपकी विशेषता की अधिकतम प्रभावी सीमा की लंबाई आपके रन की लंबाई से अधिक है, तो आपको दाएं किनारे पर तेज कोनों को पेंट करने की आवश्यकता है (बाएं से दाएं स्क्रिप्ट के लिए)। अधिक गणित आपको अगली पंक्ति के लिए हाइलाइट कोने शैली का पता लगाने देगा। :)

संलग्न प्रभाव का एक स्क्रीनशॉट है। शीर्ष पर वाला बॉक्स मानक UITextView है, जिसके लिए मैंने विशेषता टेक्स्ट सेट किया है। नीचे दिया गया बॉक्स वह है जो उपर्युक्त चरणों का उपयोग करके लागू किया गया है। टेक्स्टव्यू दोनों के लिए वही जिम्मेदार स्ट्रिंग सेट की गई है। custom attribute with rounded corners

फिर, अगर मैंने उपयोग किए गए एक से बेहतर दृष्टिकोण है, तो कृपया मुझे बताएं! : डी

आशा है कि यह समुदाय की सहायता करे। :)

चीयर्स!

+1

लेबल के पीछे एक गोलाकार रेक्ट सबव्यू जोड़ें जोड़ें क्या आपके पास कुछ नमूना कोड है जिसे आप साझा कर सकते हैं? – ddiego

+0

हैलो। आम तौर पर, मैं उस कोड को पेस्ट करता हूं जिसे मैंने किसी दिए गए कार्यान्वयन के लिए उपयोग किया है। दुर्भाग्य से, मैं इस विशेष मामले के लिए ऐसा नहीं कर सकता। :(इसके बारे में क्षमा करें। – codeBearer

+0

मैं इसकी सराहना कर सकता हूं। लेकिन अगर आप अपना दिमाग बदलते हैं और कुछ स्निपेट पोस्ट करना चाहते हैं, तो यह सहायक होगा। मैं आपके निर्देशों का पालन करने में असमर्थ हूं। – ddiego

संबंधित मुद्दे