IOS में UITextView में जिम्मेदार पाठ पर टैप का पता लगाना


122

मैं जो एक UITextViewप्रदर्शित करता है एक NSAttributedString। इस स्ट्रिंग में वे शब्द हैं जिन्हें मैं टेप करने योग्य बनाना चाहता हूं, जैसे कि जब वे टैप किए जाते हैं तो मुझे वापस बुलाया जाता है ताकि मैं एक कार्रवाई कर सकूं। मुझे लगता है कि UITextViewएक URL पर टैप का पता लगा सकते हैं और मेरे प्रतिनिधि को वापस बुला सकते हैं, लेकिन ये URL नहीं हैं।

यह मुझे लगता है कि iOS 7 और TextKit की शक्ति के साथ यह अब संभव होना चाहिए, हालांकि मुझे कोई उदाहरण नहीं मिल रहा है और मुझे यकीन नहीं है कि कहां से शुरू करना है।

मैं समझता हूं कि अब स्ट्रिंग में कस्टम विशेषताएँ बनाना संभव है (हालांकि मैंने अभी तक ऐसा नहीं किया है), और शायद ये पता लगाने के लिए उपयोगी होगा कि क्या जादू के किसी एक शब्द को टैप किया गया है? किसी भी स्थिति में, मुझे अभी भी नहीं पता है कि उस टैप को कैसे इंटरसेप्ट किया जाए और यह पता लगाया जाए कि टैप किस शब्द पर हुआ है।

ध्यान दें कि iOS 6 संगतता की आवश्यकता नहीं है।

जवाबों:


118

मैं बस दूसरों की थोड़ी और मदद करना चाहता था। Shmidt की प्रतिक्रिया के बाद यह ठीक उसी तरह संभव है जैसा मैंने अपने मूल प्रश्न में पूछा था।

1) क्लिक करने योग्य शब्दों पर लागू कस्टम विशेषताओं के साथ एक जिम्मेदार स्ट्रिंग बनाएं। जैसे।

NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:@"a clickable word" attributes:@{ @"myCustomTag" : @(YES) }];
[paragraph appendAttributedString:attributedString];

2) उस स्ट्रिंग को प्रदर्शित करने के लिए एक UITextView बनाएं और उसमें एक UITapGestureRecognizer जोड़ें। फिर नल को संभालें:

- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
    UITextView *textView = (UITextView *)recognizer.view;

    // Location of the tap in text-container coordinates

    NSLayoutManager *layoutManager = textView.layoutManager;
    CGPoint location = [recognizer locationInView:textView];
    location.x -= textView.textContainerInset.left;
    location.y -= textView.textContainerInset.top;

    // Find the character that's been tapped on

    NSUInteger characterIndex;
    characterIndex = [layoutManager characterIndexForPoint:location
                                           inTextContainer:textView.textContainer
                  fractionOfDistanceBetweenInsertionPoints:NULL];

    if (characterIndex < textView.textStorage.length) {

        NSRange range;
        id value = [textView.attributedText attribute:@"myCustomTag" atIndex:characterIndex effectiveRange:&range];

        // Handle as required...

        NSLog(@"%@, %d, %d", value, range.location, range.length);

    }
}

इतना आसान जब आप जानते हैं कि कैसे!


आप इसे IOS 6 में कैसे हल करेंगे? क्या आप कृपया इस प्रश्न पर एक नज़र डाल सकते हैं? stackoverflow.com/questions/19837522/…
स्टीफन

वास्तव में characterIndexForPoint: inTextContainer: portOfDistanceBetweenInsertionPoints iOS 6 पर उपलब्ध है, इसलिए मुझे लगता है कि इसे काम करना चाहिए। हमें बताऐ! इस प्रोजेक्ट को एक उदाहरण के लिए देखें: github.com/laevandus/NSTextFieldHyperlinks/blob/master/…
tarmes

दस्तावेज़ीकरण कहता है कि यह केवल IOS 7 या बाद में उपलब्ध है :)
स्टीफन

1
हाँ क्षमा करें। मैं मैक ओएस के साथ खुद को भ्रमित कर रहा था! यह केवल iOS7 है।
tarmes

यह काम करने के लिए प्रतीत नहीं होता है, जब आपके पास चयन योग्य UITextView नहीं है
पॉल Brewczynski

64

स्विफ्ट के साथ जिम्मेदार पाठ पर टैप का पता लगाना

कभी-कभी शुरुआती लोगों के लिए यह जानना थोड़ा कठिन होता है कि चीजों को कैसे सेट किया जाए (यह मेरे लिए वैसे भी था), इसलिए यह उदाहरण थोड़ा भरा हुआ है।

UITextViewअपने प्रोजेक्ट में जोड़ें

आउटलेट

नाम वाले आउटलेट UITextViewके ViewControllerसाथ कनेक्ट करें textView

कस्टम विशेषता

हम एक एक्सटेंशन बनाकर एक कस्टम विशेषता बनाने जा रहे हैं ।

नोट: यह चरण तकनीकी रूप से वैकल्पिक है, लेकिन यदि आप ऐसा नहीं करते हैं तो आपको मानक विशेषता का उपयोग करने के लिए अगले भाग में कोड को संपादित करने की आवश्यकता होगी NSAttributedString.Key.foregroundColor। एक कस्टम विशेषता का उपयोग करने का लाभ यह है कि आप परिभाषित पाठ श्रेणी में उन मूल्यों को परिभाषित कर सकते हैं जिन्हें आप संग्रहीत करना चाहते हैं।

फ़ाइल> नई> फ़ाइल ...> iOS> स्रोत> स्विफ्ट फ़ाइल के साथ एक नई स्विफ्ट फ़ाइल जोड़ें । इसे आप जो चाहें कह सकते हैं। मैं अपना NSAttributedStringKey + CustomAttribute.swift कह रहा हूं ।

निम्नलिखित कोड में पेस्ट करें:

import Foundation

extension NSAttributedString.Key {
    static let myAttributeName = NSAttributedString.Key(rawValue: "MyCustomAttribute")
}

कोड

निम्न के साथ ViewController.swift में कोड बदलें। ध्यान दें UIGestureRecognizerDelegate

import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create an attributed string
        let myString = NSMutableAttributedString(string: "Swift attributed text")

        // Set an attribute on part of the string
        let myRange = NSRange(location: 0, length: 5) // range of "Swift"
        let myCustomAttribute = [ NSAttributedString.Key.myAttributeName: "some value"]
        myString.addAttributes(myCustomAttribute, range: myRange)

        textView.attributedText = myString

        // Add tap gesture recognizer to Text View
        let tap = UITapGestureRecognizer(target: self, action: #selector(myMethodToHandleTap(_:)))
        tap.delegate = self
        textView.addGestureRecognizer(tap)
    }

    @objc func myMethodToHandleTap(_ sender: UITapGestureRecognizer) {

        let myTextView = sender.view as! UITextView
        let layoutManager = myTextView.layoutManager

        // location of tap in myTextView coordinates and taking the inset into account
        var location = sender.location(in: myTextView)
        location.x -= myTextView.textContainerInset.left;
        location.y -= myTextView.textContainerInset.top;

        // character index at tap location
        let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        // if index is valid then do something.
        if characterIndex < myTextView.textStorage.length {

            // print the character index
            print("character index: \(characterIndex)")

            // print the character at the index
            let myRange = NSRange(location: characterIndex, length: 1)
            let substring = (myTextView.attributedText.string as NSString).substring(with: myRange)
            print("character at index: \(substring)")

            // check if the tap location has a certain attribute
            let attributeName = NSAttributedString.Key.myAttributeName
            let attributeValue = myTextView.attributedText?.attribute(attributeName, at: characterIndex, effectiveRange: nil)
            if let value = attributeValue {
                print("You tapped on \(attributeName.rawValue) and the value is: \(value)")
            }

        }
    }
}

यहाँ छवि विवरण दर्ज करें

अब यदि आप "स्विफ्ट" के "डब्ल्यू" पर टैप करते हैं, तो आपको निम्नलिखित परिणाम प्राप्त करने चाहिए:

character index: 1
character at index: w
You tapped on MyCustomAttribute and the value is: some value

टिप्पणियाँ

  • यहां मैंने एक कस्टम विशेषता का उपयोग किया है, लेकिन यह आसानी से हो सकता है NSAttributedString.Key.foregroundColor(पाठ का रंग) जिसका मूल्य है UIColor.green
  • पूर्व में पाठ दृश्य संपादन योग्य या चयन योग्य नहीं हो सकता था, लेकिन स्विफ्ट 4.2 के लिए मेरे अद्यतन उत्तर में यह ठीक काम करता प्रतीत होता है कि ये चुने गए हैं या नहीं।

आगे के अध्ययन

यह उत्तर इस प्रश्न के कई अन्य उत्तरों पर आधारित था। इनके अलावा, यह भी देखें


myTextView.textStorageइसके बजाय का उपयोग करेंmyTextView.attributedText.string
fatihyildizhan

IOS 9 में टैप जेस्चर के माध्यम से नल का पता लगाना, लगातार नल के लिए काम नहीं करता है। उस पर कोई अपडेट?
धीरज जमी

1
@AqasMahmood, मैंने इस मुद्दे के लिए एक नया प्रश्न शुरू किया । आप इसे घूर सकते हैं और बाद में किसी भी उत्तर के लिए वापस देख सकते हैं। उस प्रश्न को संपादित करने या कोई अधिक प्रासंगिक विवरण होने पर टिप्पणी जोड़ने के लिए स्वतंत्र महसूस करें।
सुरगाछ

1
@dejix मैं अपने TextView के अंत में हर बार एक और "" खाली स्ट्रिंग जोड़कर समस्या को हल करता हूं। इस तरह आपके अंतिम शब्द के बाद पता लगना बंद हो जाता है। आशा है कि यह मदद करता है
पूलहॉलजंकी

1
कई नल के साथ पूरी तरह से काम करता है, मैं सिर्फ यह साबित करने के लिए एक छोटी दिनचर्या में डालता हूं: यदि characterIndex <12 {textView.textColor = UIColor.magenta} बाकी {textView.textColor = UIColor.blank} वास्तव में स्पष्ट और सरल कोड
जेरेमी एंड्रयूज

32

यह थोड़ा संशोधित संस्करण है, जो @tarmes उत्तर का निर्माण कर रहा है। मुझे valueकुछ भी वापस करने के लिए वैरिएबल नहीं मिल सकता है लेकिन nullनीचे दिए गए ट्वीक के बिना। इसके अलावा, परिणामी कार्रवाई को निर्धारित करने के लिए मुझे पूर्ण विशेषता शब्दकोश की आवश्यकता थी। मैंने इसे टिप्पणियों में रखा होगा, लेकिन ऐसा करने के लिए प्रतिनिधि नहीं है। अगर मैंने प्रोटोकॉल का उल्लंघन किया है तो पहले से माफी।

textView.textStorageइसके बजाय विशिष्ट ट्वीक का उपयोग करना है textView.attributedText। अभी भी आईओएस प्रोग्रामर सीखने के रूप में, मुझे वास्तव में यकीन नहीं है कि यह क्यों है, लेकिन शायद कोई और हमें बता सकता है।

नल हैंडलिंग विधि में विशिष्ट संशोधन:

    NSDictionary *attributesOfTappedText = [textView.textStorage attributesAtIndex:characterIndex effectiveRange:&range];

मेरे विचार नियंत्रक में पूर्ण कोड

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.textView.attributedText = [self attributedTextViewString];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(textTapped:)];

    [self.textView addGestureRecognizer:tap];
}  

- (NSAttributedString *)attributedTextViewString
{
    NSMutableAttributedString *paragraph = [[NSMutableAttributedString alloc] initWithString:@"This is a string with " attributes:@{NSForegroundColorAttributeName:[UIColor blueColor]}];

    NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:@"a tappable string"
                                                                       attributes:@{@"tappable":@(YES),
                                                                                    @"networkCallRequired": @(YES),
                                                                                    @"loadCatPicture": @(NO)}];

    NSAttributedString* anotherAttributedString = [[NSAttributedString alloc] initWithString:@" and another tappable string"
                                                                              attributes:@{@"tappable":@(YES),
                                                                                           @"networkCallRequired": @(NO),
                                                                                           @"loadCatPicture": @(YES)}];
    [paragraph appendAttributedString:attributedString];
    [paragraph appendAttributedString:anotherAttributedString];

    return [paragraph copy];
}

- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
    UITextView *textView = (UITextView *)recognizer.view;

    // Location of the tap in text-container coordinates

    NSLayoutManager *layoutManager = textView.layoutManager;
    CGPoint location = [recognizer locationInView:textView];
    location.x -= textView.textContainerInset.left;
    location.y -= textView.textContainerInset.top;

    NSLog(@"location: %@", NSStringFromCGPoint(location));

    // Find the character that's been tapped on

    NSUInteger characterIndex;
    characterIndex = [layoutManager characterIndexForPoint:location
                                       inTextContainer:textView.textContainer
              fractionOfDistanceBetweenInsertionPoints:NULL];

    if (characterIndex < textView.textStorage.length) {

        NSRange range;
        NSDictionary *attributes = [textView.textStorage attributesAtIndex:characterIndex effectiveRange:&range];
        NSLog(@"%@, %@", attributes, NSStringFromRange(range));

        //Based on the attributes, do something
        ///if ([attributes objectForKey:...)] //make a network call, load a cat Pic, etc

    }
}

TextView.attributedText के साथ भी यही समस्या थी! आपको textView.textStorage संकेत के लिए धन्यवाद!
काई बरगद्ट

IOS 9 में टैप जेस्चर के माध्यम से नल का पता लगाना, लगातार नल के लिए काम नहीं करता है।
धीरज जामी

25

कस्टम लिंक बनाना और जो आप टैप पर करना चाहते हैं वह iOS 7 के साथ बहुत आसान हो गया है। रे वेंडरलिच में बहुत अच्छा उदाहरण है


यह उनके कंटेनर दृश्य के सापेक्ष स्ट्रिंग स्थिति की गणना करने की कोशिश करने से ज्यादा क्लीनर समाधान है।
क्रिस सी

2
समस्या यह है कि textView को चयन करने की आवश्यकता है, और मुझे यह व्यवहार नहीं चाहिए।
थॉमसन कैलमोन

@ ThomásC। +1 के लिए पॉइंटर पर, मेरे UITextViewलिंक के बारे में पता नहीं क्यों तब भी जब मैंने इसे आईबी के माध्यम से पता लगाने के लिए सेट किया था। (मैंने इसे भी
अचूक

13

WWDC 2013 का उदाहरण :

NSLayoutManager *layoutManager = textView.layoutManager;
 CGPoint location = [touch locationInView:textView];
 NSUInteger characterIndex;
 characterIndex = [layoutManager characterIndexForPoint:location
inTextContainer:textView.textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
if (characterIndex < textView.textStorage.length) { 
// valid index
// Find the word range here
// using -enumerateSubstringsInRange:options:usingBlock:
}

धन्यवाद! मैं WWDC वीडियो भी देखूंगा।
tarmes

@Suragch "उन्नत पाठ लेआउट और पाठ किट के साथ प्रभाव"।
शाम 11

10

मैं इस सुंदर बस NSLinkAttributeName के साथ हल करने में सक्षम था

स्विफ्ट 2

class MyClass: UIViewController, UITextViewDelegate {

  @IBOutlet weak var tvBottom: UITextView!

  override func viewDidLoad() {
      super.viewDidLoad()

     let attributedString = NSMutableAttributedString(string: "click me ok?")
     attributedString.addAttribute(NSLinkAttributeName, value: "cs://moreinfo", range: NSMakeRange(0, 5))
     tvBottom.attributedText = attributedString
     tvBottom.delegate = self

  }

  func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
      UtilityFunctions.alert("clicked", message: "clicked")
      return false
  }

}

आपको यह जांचना चाहिए कि आपका URL टैप किया गया था न कि कथन के साथ if URL.scheme == "cs"और उसके return trueबाहर एक और URL ifताकि टैप किए गए UITextViewसामान्य https://लिंक को संभाल सकें
डैनियल स्टॉर्म

मैंने ऐसा किया है और यह iPhone 6 और 6+ पर काफी अच्छी तरह से काम करता है, लेकिन iPhone 5 पर बिल्कुल भी काम नहीं किया। ऊपर दिए गए Suragch सॉल्यूशन के साथ काम किया, जो अभी काम करता है। कभी पता नहीं क्यों iPhone 5 इस के साथ एक समस्या होगी, कोई मतलब नहीं है।
n13

9

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

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
}

और फिर आप shouldInteractWith URLUITextViewDelegate प्रतिनिधि पद्धति के साथ कार्रवाई को पकड़ सकते हैं। सुनिश्चित करें कि आपने प्रतिनिधि को ठीक से सेट किया है।

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
    }

बुद्धिमान की तरह आप अपनी आवश्यकता के अनुसार कोई भी कार्य कर सकते हैं।

चीयर्स !!


धन्यवाद! तुम मेरा दिन बचाओ!
Dmih

4

ऐसा होना संभव है characterIndexForPoint:inTextContainer:fractionOfDistanceBetweenInsertionPoints:। यह कुछ अलग तरह से काम करेगा जो आप चाहते थे - आपको परीक्षण करना होगा कि क्या कोई टैप किया गया चरित्र जादू शब्द से संबंधित है । लेकिन यह जटिल नहीं होना चाहिए।

BTW मैं अत्यधिक WWDC 2013 से टेक्स्ट किट पेश करने की सलाह देता हूं ।


4

स्विफ्ट 5 और आईओएस 12 के साथ, आप कुछ टेक्सटिट कार्यान्वयन के साथ एक उप-वर्ग बना सकते हैं UITextViewऔर point(inside:with:)इसमें कुछ को टैप करने योग्य बना सकते हैं NSAttributedStrings


निम्न कोड दिखाता है कि कैसे बनाने के लिए UITextViewकेवल उस पर रेखांकित NSAttributedStringएस पर नल पर प्रतिक्रिया करता है:

InteractiveUnderlinedTextView.swift

import UIKit

class InteractiveUnderlinedTextView: UITextView {

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }

    func configure() {
        isScrollEnabled = false
        isEditable = false
        isSelectable = false
        isUserInteractionEnabled = true
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let superBool = super.point(inside: point, with: event)

        let characterIndex = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
        guard characterIndex < textStorage.length else { return false }
        let attributes = textStorage.attributes(at: characterIndex, effectiveRange: nil)

        return superBool && attributes[NSAttributedString.Key.underlineStyle] != nil
    }

}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let linkTextView = InteractiveUnderlinedTextView()
        linkTextView.backgroundColor = .orange

        let mutableAttributedString = NSMutableAttributedString(string: "Some text\n\n")
        let attributes = [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue]
        let underlinedAttributedString = NSAttributedString(string: "Some other text", attributes: attributes)
        mutableAttributedString.append(underlinedAttributedString)
        linkTextView.attributedText = mutableAttributedString

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(underlinedTextTapped))
        linkTextView.addGestureRecognizer(tapGesture)

        view.addSubview(linkTextView)
        linkTextView.translatesAutoresizingMaskIntoConstraints = false
        linkTextView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        linkTextView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        linkTextView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true

    }

    @objc func underlinedTextTapped(_ sender: UITapGestureRecognizer) {
        print("Hello")
    }

}

नमस्ते, क्या यह केवल एक के बजाय कई विशेषताओं के अनुरूप बनाने का कोई तरीका है?
डेविड लिंटिन

1

यह संक्षिप्त लिंक के साथ ओके पर काम कर सकता है, एक टेक्स्टव्यू में गुणा कर सकता है। यह iOS 6,7,8 के साथ ओके काम करता है।

- (void)tappedTextView:(UITapGestureRecognizer *)tapGesture {
    if (tapGesture.state != UIGestureRecognizerStateEnded) {
        return;
    }
    UITextView *textView = (UITextView *)tapGesture.view;
    CGPoint tapLocation = [tapGesture locationInView:textView];

    NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink|NSTextCheckingTypePhoneNumber
                                                           error:nil];
    NSArray* resultString = [detector matchesInString:self.txtMessage.text options:NSMatchingReportProgress range:NSMakeRange(0, [self.txtMessage.text length])];
    BOOL isContainLink = resultString.count > 0;

    if (isContainLink) {
        for (NSTextCheckingResult* result in  resultString) {
            CGRect linkPosition = [self frameOfTextRange:result.range inTextView:self.txtMessage];

            if(CGRectContainsPoint(linkPosition, tapLocation) == 1){
                if (result.resultType == NSTextCheckingTypePhoneNumber) {
                    NSString *phoneNumber = [@"telprompt://" stringByAppendingString:result.phoneNumber];
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
                }
                else if (result.resultType == NSTextCheckingTypeLink) {
                    [[UIApplication sharedApplication] openURL:result.URL];
                }
            }
        }
    }
}

 - (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView
{
    UITextPosition *beginning = textView.beginningOfDocument;
    UITextPosition *start = [textView positionFromPosition:beginning offset:range.location];
    UITextPosition *end = [textView positionFromPosition:start offset:range.length];
    UITextRange *textRange = [textView textRangeFromPosition:start toPosition:end];
    CGRect firstRect = [textView firstRectForRange:textRange];
    CGRect newRect = [textView convertRect:firstRect fromView:textView.textInputView];
    return newRect;
}

IOS 9 में टैप जेस्चर के माध्यम से नल का पता लगाना, लगातार नल के लिए काम नहीं करता है।
धीरज जामी

1

स्विफ्ट के लिए इस एक्सटेंशन का उपयोग करें:

import UIKit

extension UITapGestureRecognizer {

    func didTapAttributedTextInTextView(textView: UITextView, inRange targetRange: NSRange) -> Bool {
        let layoutManager = textView.layoutManager
        let locationOfTouch = self.location(in: textView)
        let index = layoutManager.characterIndex(for: locationOfTouch, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        return NSLocationInRange(index, targetRange)
    }
}

UITapGestureRecognizerनिम्नलिखित चयनकर्ता के साथ अपने पाठ दृश्य में जोड़ें :

guard let text = textView.attributedText?.string else {
        return
}
let textToTap = "Tap me"
if let range = text.range(of: tapableText),
      tapGesture.didTapAttributedTextInTextView(textView: textTextView, inRange: NSRange(range, in: text)) {
                // Tap recognized
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.