सामान्य तौर पर, यदि हम UILabel द्वारा प्रदर्शित पाठ में एक क्लिक करने योग्य लिंक चाहते हैं, तो हमें दो स्वतंत्र कार्यों को हल करने की आवश्यकता होगी:
- लिंक की तरह दिखने के लिए पाठ के एक हिस्से की उपस्थिति को बदलना
- लिंक पर स्पर्श का पता लगाना और संभालना (URL खोलना एक विशेष मामला है)
पहला आसान है। आईओएस 6 से शुरू यूआईलेबेल जिम्मेदार तार के प्रदर्शन का समर्थन करता है। NSMutableAttributedString की एक आवृत्ति बनाने और कॉन्फ़िगर करने के लिए आपको बस इतना करना है:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"String with a link" attributes:nil];
NSRange linkRange = NSMakeRange(14, 4); // for the word "link" in the string above
NSDictionary *linkAttributes = @{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };
[attributedString setAttributes:linkAttributes range:linkRange];
// Assign attributedText to UILabel
label.attributedText = attributedString;
बस! उपरोक्त कोड एक लिंक के साथ स्ट्रिंग प्रदर्शित करने के लिए UILabel बनाता है
अब हमें इस लिंक पर स्पर्श का पता लगाना चाहिए। विचार यह है कि यूआईलैब के भीतर सभी नल को पकड़ना है और यह पता लगाना है कि क्या नल का स्थान लिंक के काफी करीब था। स्पर्शों को पकड़ने के लिए हम लेबल पर टैप जेस्चर पहचानकर्ता जोड़ सकते हैं। लेबल के लिए userInteraction सक्षम करना सुनिश्चित करें, यह डिफ़ॉल्ट रूप से बंद है:
label.userInteractionEnabled = YES;
[label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel:)]];
अब सबसे अधिक परिष्कृत सामान: यह पता लगाना कि नल कहां था, जहां लिंक प्रदर्शित किया गया है और लेबल के किसी अन्य हिस्से पर नहीं। यदि हमारे पास एकल-पंक्तिवाला यूलेबेल होता है, तो यह कार्य उस क्षेत्र की सीमा को हार्डकॉन्ड करके अपेक्षाकृत आसान तरीके से हल किया जा सकता है जहां लिंक प्रदर्शित होता है, लेकिन आइए इस समस्या को अधिक सुरुचिपूर्ण ढंग से और सामान्य स्थिति के लिए हल करें - लिंक लेआउट के बारे में प्रारंभिक जानकारी के बिना बहु-यूआईबेल।
IOS 7 में प्रस्तुत पाठ किट एपीआई की क्षमताओं का उपयोग करने के लिए एक दृष्टिकोण है:
// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
// Configure layoutManager and textStorage
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
// Configure textContainer
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = label.lineBreakMode;
textContainer.maximumNumberOfLines = label.numberOfLines;
अपनी कक्षा में गुणों में NSLayoutManager, NSTextContainer और NSTextStorage के बनाए और कॉन्फ़िगर किए गए इंस्टेंस को सहेजें (सबसे अधिक संभावना UIViewController के वंशज) - हमें उन्हें अन्य तरीकों की आवश्यकता होगी।
अब, हर बार लेबल अपना फ़्रेम बदलता है, टेक्स्ट कॉन्टेनर का आकार अपडेट करें:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.textContainer.size = self.label.bounds.size;
}
और अंत में, पता लगाएँ कि क्या नल ठीक लिंक पर था:
- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture
{
CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
CGSize labelSize = tapGesture.view.bounds.size;
CGRect textBoundingBox = [self.layoutManager usedRectForTextContainer:self.textContainer];
CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
locationOfTouchInLabel.y - textContainerOffset.y);
NSInteger indexOfCharacter = [self.layoutManager characterIndexForPoint:locationOfTouchInTextContainer
inTextContainer:self.textContainer
fractionOfDistanceBetweenInsertionPoints:nil];
NSRange linkRange = NSMakeRange(14, 4); // it's better to save the range somewhere when it was originally used for marking link in attributed string
if (NSLocationInRange(indexOfCharacter, linkRange)) {
// Open an URL, or handle the tap on the link in any other way
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]];
}
}
Swift 4
। यह उपयोग करता हैUITextView
लेकिन यह एक की तरह व्यवहार करता हैUILabel
। मैंने यहां समाधानों की कोशिश की, और सटीक लिंक का पता लगाने में विफल रहा।