मैं NSAttributedString में एक क्लिक करने योग्य लिंक कैसे बना सकता हूं?


200

हाइपरलिंक को क्लिक करने योग्य बनाने के लिए यह तुच्छ है UITextView। आप बस आईबी में दृश्य पर "लिंक का पता लगाएं" चेकबॉक्स सेट करते हैं, और यह HTTP लिंक का पता लगाता है और उन्हें हाइपरलिंक में बदल देता है।

हालांकि, इसका मतलब यह है कि उपयोगकर्ता जो भी देखता है वह "कच्चा" लिंक है। RTF फ़ाइलें और HTML दोनों आपको एक उपयोगकर्ता-पढ़ने योग्य स्ट्रिंग को "पीछे" एक लिंक के साथ सेट करने की अनुमति देते हैं।

किसी टेक्स्ट व्यू (या उस मामले के लिए UILabelया तो UITextField।) पर टेक्स्ट को इंस्टॉल करना आसान है। हालांकि, जब उस टेक्स्ट में एक लिंक शामिल होता है, तो यह क्लिक करने योग्य नहीं होता है।

क्या उपयोगकर्ता-पढ़ने योग्य पाठ को क्लिक करने योग्य बनाने का एक तरीका है UITextView, UILabelया UITextField?

एसओ पर मार्कअप अलग है, लेकिन यहां सामान्य विचार है। मैं जो चाहता हूं वह इस तरह है:

यह मॉर्फ फेस डांसर के साथ जनरेट किया गया था , ऐप स्टोर में देखने के लिए क्लिक करें।

केवल एक चीज मुझे मिल सकती है:

इस मॉर्फ को फेस डांसर के साथ जेनरेट किया गया था, ऐप स्टोर में देखने के लिए http://example.com/facedancer पर क्लिक करें ।


इस नमूने की कोशिश करें .. IFTweetLabel आशा है कि यह मदद करता है ..
Vidhyanand


एक आँख की झपकी में 100K अतीत उड़ाने के लिए अच्छा काम। 100K क्लब में आपका स्वागत है। अच्छी तरह से लायक!
वाकावा

@vacawama, रुको, ऐसा कब हुआ? मैं पिछली बार !98k पर था मैंने देखा! (मैं अफवाहें सुनता हूं कि आपको 100k क्लब के सदस्य के रूप में कुछ एसओ स्वैग मिलते हैं?)
डंकन सी

उन्होंने प्रश्न +5 से +10 तक बदल दिए, इसलिए यदि आपके पास 800 upvotes थे, तो आप एक फ्लैश में +4000 शुद्ध करेंगे। मैं अभी भी 100k स्वैग (अप्रैल में पार) का इंतजार कर रहा हूं।
स्वैग

जवाबों:


156

NSMutableAttributedString का उपयोग करें ।

NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@"Google"];
[str addAttribute: NSLinkAttributeName value: @"http://www.google.com" range: NSMakeRange(0, str.length)];
yourTextView.attributedText = str;

संपादित करें :

यह सीधे सवाल के बारे में नहीं है, बल्कि स्पष्ट करने के लिए है, UITextFieldऔर UILabelURL खोलने का समर्थन नहीं करता है। यदि आप UILabelलिंक के साथ उपयोग करना चाहते हैं तो आप TTTAttributedLabel की जांच कर सकते हैं ।

साथ ही आपको क्लिक करने पर URL खोलने के लिए या dataDetectorTypesअपने मान को सेट करना चाहिए । या आप टिप्पणियों में सुझाए अनुसार प्रतिनिधि विधि का उपयोग कर सकते हैं।UITextViewUIDataDetectorTypeLinkUIDataDetectorTypeAll


7
हाँ, यह काम कर रहा है, बस इसे एक UITextView के अंदर रखें और प्रतिनिधि विधि को ओवरराइड करें: - (BOOL) textView: (UITextView *) textView shouldInteractWithURL: (NSURL *) url inRange: (NSRange) characterRange
यूनुस नेदिम मेहल

यह एक UILabel में काम नहीं करता है - जब आप फ़ील्ड को टैप करते हैं तो कुछ भी नहीं होता है।
जैक बेनिम्बल

7
जब लिंक क्लिक किया जाता है तो @saboehnke का क्या मतलब है? यदि ऐसा है तो प्रतिनिधि पद्धति को लागू करें, विशेषता के रूप में एक डमी url दें और अपने तरीके को कॉल करें- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
ujell

2
मुझे नहीं पता कि इसका काम कैसा है। गुण का मान होना चाहिए NSURL। ----[str addAttribute: NSLinkAttributeName value: [NSURL URLWithString:@"http://www.google.com"] range: NSMakeRange(0, str.length)];
नीरव डांगी

1
@ नीरवदंगी सेNSAttributedString.h UIKIT_EXTERN NSString * const NSLinkAttributeName NS_AVAILABLE(10_0, 7_0); // NSURL (preferred) or NSString
अहमद नवार

142

मुझे यह वास्तव में उपयोगी लगा, लेकिन मुझे इसे कुछ जगहों पर करने की आवश्यकता थी इसलिए मैंने अपने दृष्टिकोण को एक साधारण विस्तार में लपेट लिया है NSMutableAttributedString:

स्विफ्ट 3

extension NSMutableAttributedString {

    public func setAsLink(textToFind:String, linkURL:String) -> Bool {

        let foundRange = self.mutableString.range(of: textToFind)
        if foundRange.location != NSNotFound {
            self.addAttribute(.link, value: linkURL, range: foundRange)
            return true
        }
        return false
    }
}

स्विफ्ट 2

import Foundation

extension NSMutableAttributedString {

   public func setAsLink(textToFind:String, linkURL:String) -> Bool {

       let foundRange = self.mutableString.rangeOfString(textToFind)
       if foundRange.location != NSNotFound {
           self.addAttribute(NSLinkAttributeName, value: linkURL, range: foundRange)
           return true
       }
       return false
   }
}

उदाहरण का उपयोग:

let attributedString = NSMutableAttributedString(string:"I love stackoverflow!")
let linkWasSet = attributedString.setAsLink("stackoverflow", linkURL: "http://stackoverflow.com")

if linkWasSet {
    // adjust more attributedString properties
}

उद्देश्य सी

मैंने सिर्फ एक शुद्ध उद्देश्य-सी परियोजना में ही ऐसा करने की आवश्यकता को मारा है, इसलिए यहाँ उद्देश्य-सी श्रेणी है।

@interface NSMutableAttributedString (SetAsLinkSupport)

- (BOOL)setAsLink:(NSString*)textToFind linkURL:(NSString*)linkURL;

@end


@implementation NSMutableAttributedString (SetAsLinkSupport)

- (BOOL)setAsLink:(NSString*)textToFind linkURL:(NSString*)linkURL {

     NSRange foundRange = [self.mutableString rangeOfString:textToFind];
     if (foundRange.location != NSNotFound) {
         [self addAttribute:NSLinkAttributeName value:linkURL range:foundRange];
         return YES;
     }
     return NO;
}

@end

उदाहरण का उपयोग:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:"I love stackoverflow!"];

BOOL linkWasSet = [attributedString setAsLink:@"stackoverflow" linkURL:@"http://stackoverflow.com"];

if (linkWasSet) {
    // adjust more attributedString properties
}

सुनिश्चित करें कि NSTextField's Behavior विशेषता चयन योग्य के रूप में सेट है। Xcode NSTextField व्यवहार विशेषता


इस का एक त्वरित उपयोग / कार्यान्वयन उदाहरण बहुत सराहना की जाएगी।
1

3
@ioop। मैंने ऊपर मूल पोस्ट में एक बहुत छोटा उदाहरण जोड़ा है, आशा है कि मदद करता है।
कार्ल नोसवर्थी

7
यह सही ढंग से काम किया। बस इतना कहना चाहता हूं कि आपको अपने UITextView को क्लिक करने योग्य बनाने के लिए चयन करने योग्य बनाने की आवश्यकता है
lujop

1
उद्देश्य सी और स्विफ्ट कार्यान्वयन दोनों में @felecia जीनेट यह इंगित करने के लिए एक बूलियन परिणाम देता है कि क्या मैच और परिणामस्वरूप सेट हुआ। जो त्रुटि आप देख रहे हैं, क्योंकि आप उस परिणाम को कैप्चर नहीं कर रहे हैं - जो ठीक है। आप या तो उस परिणाम को स्थानीय चर पर असाइन करके कैप्चर कर सकते हैं या बूलियन मान को वापस करने के लिए विधि को समायोजित कर सकते हैं यदि वह आपकी आवश्यकताओं के अनुसार बेहतर हो। मुझे आशा है कि वह मदद करेंगे?
कार्ल नोसवर्थी

1
कोई समस्या नहीं @feleciagenet, मैंने स्विफ्ट और ObjectiveC दोनों उदाहरणों के लिए विधि के भंडारण और जाँच को जोड़ा है।
कार्ल नोसवर्थी

34

मैंने यूआईबेल का एक उपवर्ग बनाया, विशेष रूप से ऐसे उपयोग मामलों को संबोधित करने के लिए। आप आसानी से कई लिंक जोड़ सकते हैं और उनके लिए अलग हैंडलर परिभाषित कर सकते हैं। जब आप टच फीडबैक के लिए टच करते हैं तो यह दबाए गए लिंक को हाइलाइट करने का भी समर्थन करता है। कृपया https://github.com/null09264/FRHyperLabel देखें

आपके मामले में, कोड इस तरह हो सकता है:

FRHyperLabel *label = [FRHyperLabel new];

NSString *string = @"This morph was generated with Face Dancer, Click to view in the app store.";
NSDictionary *attributes = @{NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]};

label.attributedText = [[NSAttributedString alloc]initWithString:string attributes:attributes];

[label setLinkForSubstring:@"Face Dancer" withLinkHandler:^(FRHyperLabel *label, NSString *substring){
    [[UIApplication sharedApplication] openURL:aURL];
}];

नमूना स्क्रीनशॉट (हैंडलर इस मामले में एक यूआरएल खोलने के बजाय एक चेतावनी पॉप करने के लिए सेट है)

facedancer


अगर मान लें कि मेरा पाठ ऐसा है तो यह मॉर्फ फेस डांसर के साथ उत्पन्न हुआ था, ऐप स्टोर फेस डांसर में क्लिक टू फेस डांसर देखें। यहाँ मैं 3 फेस डांसर कर रहा हूँ यह इसके लिए काम नहीं कर रहा था
MANCHIKANTI KRISHNAKISHORE

1
इस स्थिति में कृपया - (void)setLinkForRange:(NSRange)range withLinkHandler:(void(^)(FRHyperLabel *label, NSRange selectedRange))handler; इसके बजाय एपीआई का उपयोग करें । कृपया गिठब पृष्ठ में रीडमे को देखें।
जिंगन वांग

1
FRHyperLabel अब काम नहीं कर रही है। "CharacterIndexForPoint:" के अंदर, यह हमेशा -1 (नहीं मिला) लौटाता है।
जॉन पैंग

मल्टीलाइन लेबल के लिए मेरे लिए काम नहीं करता है। पात्रों का पता लगाना गलत है। 15-वर्ण लिंक स्ट्रिंग केवल कुछ प्रथम वर्णों पर क्लिक करने योग्य है, अन्य वर्ण कुछ भी नहीं करते हैं
Accid Bright

27

Ujell के समाधान में मामूली सुधार: यदि आप NSString के बजाय NSURL का उपयोग करते हैं, तो आप किसी भी URL (जैसे कस्टम यूआरएल) का उपयोग कर सकते हैं

NSURL *URL = [NSURL URLWithString: @"whatsapp://app"];
NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@"start Whatsapp"];
[str addAttribute: NSLinkAttributeName value:URL range: NSMakeRange(0, str.length)];
yourTextField.attributedText = str;

मज़े करो!


21

स्विफ्ट 4:

var string = "Google"
var attributedString = NSMutableAttributedString(string: string, attributes:[NSAttributedStringKey.link: URL(string: "http://www.google.com")!])

yourTextView.attributedText = attributedString

स्विफ्ट 3.1:

var string = "Google"
var attributedString = NSMutableAttributedString(string: string, attributes:[NSLinkAttributeName: URL(string: "http://www.google.com")!])

yourTextView.attributedText = attributedString

यह उत्तर पूरी तरह से काम करता है। किसी भी रंग या कस्टम उपवर्ग की ज़रूरत नहीं है जो अन्य उत्तर का उपयोग करें।
शून्यकाल

19

मुझे भी इसी तरह की आवश्यकता थी, शुरू में मैंने यूबिलब का इस्तेमाल किया और फिर मुझे महसूस हुआ कि यूआईटैक्सव्यू बेहतर है। मैंने UITextView को बातचीत और स्क्रॉलिंग को अक्षम करके UILabel की तरह व्यवहार NSMutableAttributedStringकिया और कार्ल के लिए जो किया था, उसी तरह से पाठ के लिए लिंक सेट करने के लिए एक श्रेणी विधि बनाई (इसके लिए +1) यह मेरा obj c संस्करण है

-(void)setTextAsLink:(NSString*) textToFind withLinkURL:(NSString*) url
{
    NSRange range = [self.mutableString rangeOfString:textToFind options:NSCaseInsensitiveSearch];

    if (range.location != NSNotFound) {

        [self addAttribute:NSLinkAttributeName value:url range:range];
        [self addAttribute:NSForegroundColorAttributeName value:[UIColor URLColor] range:range];
    }
}

आप कार्रवाई को संभालने के लिए नीचे के प्रतिनिधि का उपयोग कर सकते हैं

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)url inRange:(NSRange)characterRange
{
    // do the task
    return YES;
}

1
जहां तक ​​मैं NSForegroundColorAttributeNameएक सीमा में सेटिंग बता सकता हूं जहां NSLinkAttributeNameलागू किया जाता है वह काम नहीं करता है। कोई बात नहीं क्या, linkTextAttributesके UITextViewबजाय लागू होते हैं। NSForegroundColorAttributeNameआपके लिए काम करता है ?
दिमा

क्या आप सुनिश्चित हैं कि आप भी linkTextAttributesउसी चीज़ को सेट नहीं कर रहे हैं ? या शायद tintColor? क्या आप एक ही टेक्स्टव्यू में अलग-अलग रंगों में 2 लिंक दिखाने में सक्षम हैं?
दीमा

1
यहाँ एक वर्किंग कोड NSRange रेंज = [self.text rangeOfString: textToFind विकल्प: NSCaseInsensitiveSearch] है; if (रेंज.लोकेशन! = NSNotFound) {NSMutableAttributedString * string = [[NSMutableAttributedString आवंटन] initWithString: self.text]; [स्ट्रिंग addAttribute: NSLinkAttributeName मान: url श्रेणी: श्रेणी]; [स्ट्रिंग addAttribute: NSForegroundColorAttributeName मान: [UIColor BlueColor] रेंज: रेंज]; self.text = @ ""; self.attributedText = string; }
नोसोव पावेल

16

UITextView का उपयोग करें यह क्लिक करने योग्य लिंक का समर्थन करता है। निम्नलिखित कोड का उपयोग करके जिम्मेदार स्ट्रिंग बनाएं

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:strSomeTextWithLinks];

फिर UITextView टेक्स्ट को निम्नानुसार सेट करें

NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor redColor],

                                 NSUnderlineColorAttributeName: [UIColor blueColor],

                                 NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

customTextView.linkTextAttributes = linkAttributes; // customizes the appearance of links
textView.attributedText = attributedString;

सुनिश्चित करें कि आप XIB में UITextView के "चयन योग्य" व्यवहार को सक्षम करते हैं।


15
मुझे लगता है कि यह सबसे अच्छा समाधान है! सक्षम करने के बारे में नोट Selectableमहत्वपूर्ण है!
लूनाकोडगर्ल

यह मेरे लिए लिंक को रेखांकित नहीं करता (iOS 7, 8)। मुझे NSUnderlineStyleAttributeName का उपयोग करने की आवश्यकता है: [NSNumber numberWithInt: NSUnderlineStyleSingle]
प्रीवेट करें

1
यह चयन करना सबसे महत्वपूर्ण और गैर सहज जानकारी है!
निकोलस मासार्ट

13

मेरे सवाल का दिल यह था कि मैं पाठ में हेरफेर करने और लिंक जोड़ने के लिए कस्टम कोड लिखने के बिना पाठ दृश्य / फ़ील्ड / लेबल में क्लिक करने योग्य लिंक बनाने में सक्षम होना चाहता था। मैं चाहता था कि यह डेटा से संचालित हो।

मैं अंत में पता लगा कि यह कैसे करना है। मुद्दा यह है कि आईबी एम्बेडेड लिंक का सम्मान नहीं करता है।

इसके अलावा, iOS संस्करण NSAttributedStringआपको RTF फ़ाइल से एक जिम्मेदार स्ट्रिंग को आरंभ करने की अनुमति नहीं देता है। के ओएस एक्स संस्करण NSAttributedString करता है एक प्रारंभकर्ता कि इनपुट के रूप में एक RTF फ़ाइल लेता है।

NSAttributedString NSCoding प्रोटोकॉल के अनुरूप है, इसलिए आप इसे NSData से / में परिवर्तित कर सकते हैं

मैंने एक OS X कमांड लाइन उपकरण बनाया जो इनपुट के रूप में RTF फ़ाइल लेता है और एक्सटेंशन के साथ एक फ़ाइल को आउटपुट करता है। जिसमें NSCoding से NSData होता है। मैंने तब अपनी परियोजना में .data फ़ाइल डाल दी और कोड की कुछ पंक्तियाँ जोड़ दीं जो पाठ को दृश्य में लोड करती हैं। कोड इस तरह दिखता है (यह परियोजना स्विफ्ट में थी):

/*
If we can load a file called "Dates.data" from the bundle and convert it to an attributed string,
install it in the dates field. The contents contain clickable links with custom URLS to select
each date.
*/
if
  let datesPath = NSBundle.mainBundle().pathForResource("Dates", ofType: "data"),
  let datesString = NSKeyedUnarchiver.unarchiveObjectWithFile(datesPath) as? NSAttributedString
{
  datesField.attributedText = datesString
}

उन ऐप्स के लिए जो बहुत सारे स्वरूपित पाठ का उपयोग करते हैं, मैं एक बिल्ड नियम बनाता हूं जो Xcode को बताता है कि किसी दिए गए फ़ोल्डर में सभी .rtf फाइलें स्रोत हैं और .data फाइलें आउटपुट हैं। एक बार जब मैं ऐसा करता हूं, तो मैं केवल निर्दिष्ट निर्देशिका में .rtf फ़ाइलों को जोड़ता हूं, (या मौजूदा फ़ाइलों को संपादित करता हूं) और निर्माण प्रक्रिया के आंकड़े बताता हूं कि वे नए / अपडेट हैं, कमांड लाइन टूल चलाते हैं, और फ़ाइलों को ऐप बंडल में कॉपी करते हैं। यह खूबसूरती से काम करता है।

मैंने एक ब्लॉग पोस्ट लिखा है जो तकनीक के प्रदर्शन के लिए एक नमूना (स्विफ्ट) परियोजना से जुड़ा हुआ है। आप इसे यहां देख सकते हैं:

UITextField में क्लिक करने योग्य URL बनाना जो आपके ऐप में खुले


11

जिम्मेदार पाठ नल पर कार्रवाई का पता लगाने के लिए 3 उदाहरण स्विफ्ट

https://stackoverflow.com/a/44226491/5516830

let termsAndConditionsURL = TERMS_CONDITIONS_URL;
let privacyURL            = PRIVACY_URL;

override func viewDidLoad() {
    super.viewDidLoad()

    self.txtView.delegate = self
    let str = "By continuing, you accept the Terms of use and Privacy policy"
    let attributedString = NSMutableAttributedString(string: str)
    var foundRange = attributedString.mutableString.range(of: "Terms of use") //mention the parts of the attributed text you want to tap and get an custom action
    attributedString.addAttribute(NSLinkAttributeName, value: termsAndConditionsURL, range: foundRange)
    foundRange = attributedString.mutableString.range(of: "Privacy policy")
    attributedString.addAttribute(NSLinkAttributeName, value: privacyURL, range: foundRange)
    txtView.attributedText = attributedString
}

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "WebView") as! SKWebViewController

    if (URL.absoluteString == termsAndConditionsURL) {
        vc.strWebURL = TERMS_CONDITIONS_URL
        self.navigationController?.pushViewController(vc, animated: true)
    } else if (URL.absoluteString == privacyURL) {
        vc.strWebURL = PRIVACY_URL
        self.navigationController?.pushViewController(vc, animated: true)
    }
    return false
}

बुद्धिमान की तरह आप अपने साथ कोई भी कार्रवाई जोड़ सकते हैं shouldInteractWith URL UITextFieldDelegate विधि के ।

चीयर्स !!


7

त्वरित उत्तर यूआईलैब के बजाय UITextView का उपयोग कर रहा है। आपको सक्षम Selectableऔर अक्षम करने की आवश्यकता हैEditable

फिर स्क्रॉल संकेतक और बाउंस को अक्षम करें।

स्क्रीन शॉट

स्क्रीन शॉट

NSMutableAttributedStringHTML स्ट्रिंग से मेरा समाधानNSHTMLTextDocumentType

NSString *s = @"<p><a href='https://itunes.apple.com/us/app/xxxx/xxxx?mt=8'>https://itunes.apple.com/us/app/xxxx/xxxx?mt=8</a></p>";

NSMutableAttributedString *text = [[NSMutableAttributedString alloc]
                                           initWithData: [s dataUsingEncoding:NSUnicodeStringEncoding]
                                           options: @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType }
                                           documentAttributes: nil
                                           error: nil
                                           ];

cell.content.attributedText = text;

यह। मैं अपने संसाधन बंडल से RTF फ़ाइल पढ़ने में सक्षम था NSAttributedString, इसे attributedTextमेरे UITextViewऔर हाइपरलिंक के काम के रूप में सेट करूं यह प्रत्येक हाइपरलिंक की सीमा को खोजने और विशेषताओं का उपयोग करके इसे स्थापित करने के लिए बहुत काम होता।
निकोलस मिआरी

6

मैंने एक विधि लिखी है, जो एक कड़ी (फुलस्ट्रिंग) से एक कड़ी (लिंकस्ट्रिंग) को एक निश्चित यूआरएल (urlString) के साथ जोड़ता है:

- (NSAttributedString *)linkedStringFromFullString:(NSString *)fullString withLinkString:(NSString *)linkString andUrlString:(NSString *)urlString
{
    NSRange range = [fullString rangeOfString:linkString options:NSLiteralSearch];
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:fullString];

    NSMutableParagraphStyle *paragraphStyle = NSMutableParagraphStyle.new;
    paragraphStyle.alignment = NSTextAlignmentCenter;
    NSDictionary *attributes = @{NSForegroundColorAttributeName:RGB(0x999999),
                                 NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue-Light" size:10],
                                 NSParagraphStyleAttributeName:paragraphStyle};
    [str addAttributes:attributes range:NSMakeRange(0, [str length])];
    [str addAttribute: NSLinkAttributeName value:urlString range:range];

    return str;
}

आपको इसे इस तरह से कॉल करना चाहिए:

NSString *fullString = @"A man who bought the Google.com domain name for $12 and owned it for about a minute has been rewarded by Google for uncovering the flaw.";
NSString *linkString = @"Google.com";
NSString *urlString = @"http://www.google.com";

_youTextView.attributedText = [self linkedStringFromFullString:fullString withLinkString:linkString andUrlString:urlString];

यह क्लिक करने योग्य है, लेकिन यह लिंक या कुछ भी नहीं खोलता है। यह सिर्फ एक बटन की तरह क्लिक करता है जो कुछ भी नहीं करता है।
रेजा

5

मुझे एक शुद्ध उबेलबेल का उपयोग करने की आवश्यकता थी, इसलिए इसे मेरे नल पहचानकर्ता से कहा गया (यह यहां पुरुष की प्रतिक्रिया पर आधारित है: उइबेल के लिए स्पर्श बिंदु पर चरित्र सूचकांक )

UILabel* label = (UILabel*)gesture.view;
CGPoint tapLocation = [gesture locationInView:label];

// create attributed string with paragraph style from label

NSMutableAttributedString* attr = [label.attributedText mutableCopy];
NSMutableParagraphStyle* paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = label.textAlignment;

[attr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.attributedText.length)];

// init text storage

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attr];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];

// init text container

NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(label.frame.size.width, label.frame.size.height+100) ];
textContainer.lineFragmentPadding  = 0;
textContainer.maximumNumberOfLines = label.numberOfLines;
textContainer.lineBreakMode        = label.lineBreakMode;

[layoutManager addTextContainer:textContainer];

// find tapped character

NSUInteger characterIndex = [layoutManager characterIndexForPoint:tapLocation
                                                  inTextContainer:textContainer
                         fractionOfDistanceBetweenInsertionPoints:NULL];

// process link at tapped character

[attr enumerateAttributesInRange:NSMakeRange(characterIndex, 1)
                                         options:0
                                      usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
                                          if (attrs[NSLinkAttributeName]) {
                                              NSString* urlString = attrs[NSLinkAttributeName];
                                              NSURL* url = [NSURL URLWithString:urlString];
                                              [[UIApplication sharedApplication] openURL:url];
                                          }
                                      }];

यह काफी मददगार था, मैं अंतिम पंक्ति के पात्रों से अनुक्रमणिका प्राप्त करने में असमर्थ था। जब CGSize init'ing करने के लिए आपके कोड में textContainer पर +100 होता है, जो मेरे लिए बहुत मायने नहीं रखता है, लेकिन इसने चाल चली।
ब्लूहैड

4

अपडेट करें:

मेरे प्रश्न के 2 मुख्य भाग थे:

  1. लिंक करने के लिए कैसे जहां क्लिक करने योग्य लिंक के लिए दिखाया गया पाठ लागू किए गए वास्तविक लिंक से अलग है:
  2. पाठ पर विशेषताएँ सेट करने के लिए कस्टम कोड का उपयोग किए बिना लिंक कैसे सेट करें।

यह पता चला है कि iOS 7 ने जिम्मेदार टेक्स्ट को लोड करने की क्षमता को जोड़ा है NSData

मैंने एक कस्टम उपवर्ग बनाया जिसका UITextViewफायदा उठाता है@IBInspectable विशेषता और आपको IB में सीधे RTF फ़ाइल से सामग्री लोड करने देता है। आप बस आईबी में फ़ाइल नाम टाइप करते हैं और कस्टम वर्ग बाकी काम करता है।

यहाँ विवरण हैं:

IOS 7 में, NSAttributedStringविधि प्राप्त की initWithData:options:documentAttributes:error:। वह विधि आपको NSData ऑब्जेक्ट से एक NSAttributedString लोड करने देता है। आप पहले NSData में RTF फ़ाइल लोड कर सकते हैं, फिर initWithData:options:documentAttributes:error:उस NSData को अपने टेक्स्ट दृश्य में लोड करने के लिए उपयोग कर सकते हैं। (ध्यान दें कि एक विधि भी है initWithFileURL:options:documentAttributes:error:जो एक फ़ाइल से सीधे एक स्ट्रिंग को लोड करेगी, लेकिन उस विधि को iOS 9 में पदावनत किया गया था। यह विधि का उपयोग करने के लिए सुरक्षित है initWithData:options:documentAttributes:error:, जिसे पदावनत नहीं किया गया था।

मैं एक ऐसी विधि चाहता था जिससे मैं अपने पाठ विचारों में क्लिक करने योग्य लिंक स्थापित कर सकूं, जो मेरे द्वारा उपयोग किए जा रहे लिंक के लिए कोई कोड विशिष्ट नहीं है।

मैं जिस समाधान के साथ आया था वह UITextView I का एक कस्टम उपवर्ग बनाने के लिए था जिसे मैं कॉल करता हूं RTF_UITextViewऔर इसे एक @IBInspectableसंपत्ति देता हूं RTF_Filename। जोड़ रहा है@IBInspectable गुण विशेषता इंटरफ़ेस बिल्डर को उस संपत्ति को "इंस्पेक्टर इंस्पेक्टर।" फिर आप उस मान को IB wihtout कस्टम कोड से सेट कर सकते हैं।

मैंने @IBDesignableअपने कस्टम वर्ग में एक विशेषता भी जोड़ी है । @IBDesignableविशेषता Xcode बताता है कि यह इंटरफ़ेस बिल्डर में अपने कस्टम दृश्य वर्ग के एक चल प्रतिलिपि स्थापित करना चाहिए ताकि आप उसे अपने दृश्य पदानुक्रम के चित्रमय प्रदर्शन में देख सकते हैं। () दुर्भाग्य से, इस वर्ग के लिए, @IBDesignableसंपत्ति परतदार लगती है। जब मैंने पहली बार इसे जोड़ा तो यह काम कर रहा था, लेकिन फिर मैंने अपने पाठ दृश्य की सादे पाठ सामग्री को हटा दिया और मेरे विचार में क्लिक करने योग्य लिंक हट गए और मैं उन्हें वापस नहीं ले पाया।)

मेरे लिए कोड RTF_UITextViewबहुत सरल है। @IBDesignableविशेषता के RTF_Filenameसाथ विशेषता और एक संपत्ति को जोड़ने के अलावा @IBInspectable, मैंने संपत्ति में एक didSet()विधि जोड़ी RTF_FilenamedidSet()विधि का मूल्य किसी भी समय कहा जाता हो जाता है RTF_Filenameगुण परिवर्तन। didSet()विधि के लिए कोड काफी सरल है:

@IBDesignable
class RTF_UITextView: UITextView
{
  @IBInspectable
  var RTF_Filename: String?
    {
    didSet(newValue)
    {
      //If the RTF_Filename is nil or the empty string, don't do anything
      if ((RTF_Filename ?? "").isEmpty)
      {
        return
      }
      //Use optional binding to try to get an URL to the
      //specified filename in the app bundle. If that succeeds, try to load
      //NSData from the file.
      if let fileURL = NSBundle.mainBundle().URLForResource(RTF_Filename, withExtension: "rtf"),
        
        //If the fileURL loads, also try to load NSData from the URL.
        let theData = NSData(contentsOfURL: fileURL)
      {
        var aString:NSAttributedString
        do
        {
          //Try to load an NSAttributedString from the data
          try
            aString = NSAttributedString(data: theData,
              options: [:],
              documentAttributes:  nil
          )
          //If it succeeds, install the attributed string into the field.
          self.attributedText = aString;
        }
        catch
        {
          print("Nerp.");
        }
      }
      
    }
  }
}

ध्यान दें कि यदि @IBDesignable संपत्ति आपको इंटरफ़ेस बिल्डर में अपने स्टाइल किए गए पाठ का पूर्वावलोकन करने की अनुमति देने के लिए मज़बूती से नहीं जा रही है, तो हो सकता है कि कस्टम उपवर्ग के बजाय UITextView के विस्तार के रूप में उपरोक्त कोड को सेट करना बेहतर हो। इस तरह आप इसे कस्टम क्लास में टेक्स्ट व्यू को बदलने के बिना किसी भी टेक्स्ट व्यू में इस्तेमाल कर सकते हैं।

अगर आपको iOS 7 से पहले iOS वर्जन को सपोर्ट करने की जरूरत है तो मेरा दूसरा जवाब देखें।

आप एक नमूना परियोजना डाउनलोड कर सकते हैं जिसमें gitHub का यह नया वर्ग शामिल है:

Github पर DatesInSwift डेमो प्रोजेक्ट


3

UITextView के लिए बस एक कोड मुक्त समाधान खोजें: यहां छवि विवरण दर्ज करें

डिटेक्शन सक्षम करें-> लिंक विकल्प, यूआरएल और ईमेल का भी पता लगाया जाएगा और क्लिक करने योग्य होगा!


3
यह लिंक को क्लिक करने योग्य बनाता है। मैं उपयोगकर्ता-पठनीय पाठ रखना चाहता हूं जिसके पीछे एक लिंक है। मेरे मूल प्रश्न में उदाहरण देखें।
डंकन सी।

हां, मेरा उत्तर केवल उस मामले पर लागू होता है जब लिंक पाठ के समान होता है। यदि लिंक एक और सामान है, तो मैं @ ujell के उत्तर का पालन करूंगा।
बिल चैन

3
मेरा प्रश्न विशेष रूप से क्लिक करने योग्य पाठ के बारे में था जो URL के अलावा कुछ और प्रदर्शित करता है। आप सवाल पर नज़र से ज्यादा नहीं किया, क्या आपने?
डंकन सी।

1
दूसरों के उद्देश्य की सेवा नहीं की, लेकिन निश्चित रूप से यही वह चीज है जिसकी मुझे तलाश थी ... मेरी चैट एप्लिकेशन में लिंक बनाने का एक तरीका क्लिक करने योग्य। बिंगो मुझे यह लेख मिला ... धन्यवाद! विश xcode ट्विटर और हैश टैग सक्षम करने के लिए अनुमति देगा।
मिज़किटा

यह कच्चे लिंक के कस्टम पाठ के साथ भी काम करता है। चयन करने के लिए याद रखें व्यवहार -> चयन और पहचान -> लिंक।
krlbsk

3

स्विफ्ट संस्करण:

    // Attributed String for Label
    let plainText = "Apkia"
    let styledText = NSMutableAttributedString(string: plainText)
    // Set Attribuets for Color, HyperLink and Font Size
    let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(14.0), NSLinkAttributeName:NSURL(string: "http://apkia.com/")!, NSForegroundColorAttributeName: UIColor.blueColor()]
    styledText.setAttributes(attributes, range: NSMakeRange(0, plainText.characters.count))
    registerLabel.attributedText = styledText

3

UITextView का उपयोग करें और लिंक के लिए डेटाडाईटीपी सेट करें।

इस तरह:

testTextView.editable = false 
testTextView.dataDetectorTypes = .link

यदि आप लिंक, फोन नंबर, पता आदि का पता लगाना चाहते हैं

testTextView.dataDetectorTypes = .all

3
नहीं। यह केवल आपको लिंक को क्लिक करने योग्य बनाता है। मेरा प्रश्न "क्लिक हियर" जैसे मनमाने पाठ बनाने के लिए विशिष्ट है, न कि URL पर जैसेhttp://somedomain/someurl?param=value
डंकन सी।

2

डंकन सी के मूल विवरण के साथ एक त्वरित जोड़-ए-वी आईबी व्यवहार। वह लिखते हैं: "यह एक UITextView में हाइपरलिंक्स को क्लिक करने के लिए तुच्छ है। आप आईबी में दृश्य पर" लिंक का पता लगाएं "चेकबॉक्स सेट करते हैं, और यह http लिंक का पता लगाता है और उन्हें हाइपरलिंक में बदल देता है।"

मेरा अनुभव (कम से कम xcode 7 में) यह है कि आपको url का पता लगाने और क्लिक करने योग्य के लिए "संपादन योग्य" व्यवहार को भी अशुद्ध करना होगा।


2

अगर आपको @Karl Nosworthy और @esilver ने ऊपर दिए गए मुद्दों के साथ समस्याएँ हैं, तो मैंने अपने Swift 4 संस्करण में NSMutableAttributedString एक्सटेंशन को अपडेट किया है।

extension NSMutableAttributedString {

public func setAsLink(textToFind:String, linkURL:String) -> Bool {

    let foundRange = self.mutableString.range(of: textToFind)
    if foundRange.location != NSNotFound {
         _ = NSMutableAttributedString(string: textToFind)
        // Set Attribuets for Color, HyperLink and Font Size
        let attributes = [NSFontAttributeName: UIFont.bodyFont(.regular, shouldResize: true), NSLinkAttributeName:NSURL(string: linkURL)!, NSForegroundColorAttributeName: UIColor.blue]

        self.setAttributes(attributes, range: foundRange)
        return true
    }
    return false
  }
}


0

यदि आप एक UITextView में NSLinkAttributeName का उपयोग करना चाहते हैं, तो आप AttributedTextView लाइब्रेरी का उपयोग करने पर विचार कर सकते हैं। यह एक UITextView उपवर्ग है जो इन्हें संभालना बहुत आसान बनाता है। अधिक जानकारी के लिए देखें: https://github.com/evermeer/AttributedTextView

आप पाठ के किसी भी भाग को इस तरह से इंटरैक्ट कर सकते हैं (जहाँ textView1 एक UITextView IBoutlet है)

textView1.attributer =
    "1. ".red
    .append("This is the first test. ").green
    .append("Click on ").black
    .append("evict.nl").makeInteract { _ in
        UIApplication.shared.open(URL(string: "http://evict.nl")!, options: [:], completionHandler: { completed in })
    }.underline
    .append(" for testing links. ").black
    .append("Next test").underline.makeInteract { _ in
        print("NEXT")
    }
    .all.font(UIFont(name: "SourceSansPro-Regular", size: 16))
    .setLinkColor(UIColor.purple) 

और हैशटैग और उल्लेख को संभालने के लिए आप इस तरह कोड का उपयोग कर सकते हैं:

textView1.attributer = "@test: What #hashtags do we have in @evermeer #AtributedTextView library"
    .matchHashtags.underline
    .matchMentions
    .makeInteract { link in
        UIApplication.shared.open(URL(string: "https://twitter.com\(link.replacingOccurrences(of: "@", with: ""))")!, options: [:], completionHandler: { completed in })
    }

0

यदि आप अपने UITextView में सक्रिय विकल्प चाहते हैं तो आप मेरे विस्तारित TextView ... इसके लघु और सरल का उपयोग कर सकते हैं। आप इसे अपनी इच्छानुसार संपादित कर सकते हैं।

परिणाम: यहां छवि विवरण दर्ज करें

कोड: https://github.com/marekmand/ActiveSubstringTextView


0
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:strSomeTextWithLinks];

NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor redColor],   
                                 NSUnderlineColorAttributeName: [UIColor blueColor],
                                 NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

customTextView.linkTextAttributes = linkAttributes; // customizes the appearance of links
textView.attributedText = attributedString;

प्रमुख बिंदु:

  • सुनिश्चित करें कि आप XIB में UITextView के "चयन योग्य" व्यवहार को सक्षम करते हैं।
  • सुनिश्चित करें कि आप XIB में UITextView के "संपादन योग्य" व्यवहार को अक्षम करते हैं।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.