আইওএসের একটি ইউআইটিেক্সটভিউতে বিশিষ্ট পাঠ্যের জন্য ট্যাপগুলি সনাক্ত করা


122

আমার একটি আছে UITextViewযা প্রদর্শন করে NSAttributedString। এই স্ট্রিংয়ে এমন শব্দ রয়েছে যা আমি টেপযোগ্য করতে চাই, যেমন যখন সেগুলি টেপ করা হয় তখন আমাকে আবার কল করা হয় যাতে আমি কোনও ক্রিয়া সম্পাদন করতে পারি। আমি বুঝতে পারি যে UITextViewকোনও ইউআরএল-এ ট্যাপগুলি সনাক্ত করতে পারে এবং আমার প্রতিনিধিটিকে ফিরে কল করতে পারে, তবে এগুলি ইউআরএল নয়।

আমার কাছে মনে হয়েছে যে আইওএস 7 এবং টেক্সটকিটের শক্তির সাহায্যে এটি এখনই সম্ভব হওয়া উচিত, তবে আমি এর উদাহরণ খুঁজে পাচ্ছি না এবং আমি কোথায় শুরু করব তা নিশ্চিত নই।

আমি বুঝতে পেরেছি যে স্ট্রিংয়ে কাস্টম বৈশিষ্ট্য তৈরি করা এখন সম্ভব (যদিও আমি এটি এখনও করি নি), এবং সম্ভবত এগুলি সনাক্ত করতে কার্যকর হবে যে কোনও ম্যাজিক শব্দের সাথে ট্যাপ করা হয়েছে কিনা? যাই হোক না কেন, আমি এখনও সেই ট্যাপটিকে কীভাবে আটকাতে পারি এবং কোন শব্দটিতে ট্যাপটি উপস্থিত হয়েছিল তা সনাক্ত করব।

মনে রাখবেন যে, আইওএস 6 সামঞ্জস্য হয় না প্রয়োজন।

উত্তর:


118

আমি কেবল অন্যদের আরও কিছুটা সাহায্য করতে চেয়েছিলাম। শ্মিতের প্রতিক্রিয়া অনুসরণ করে আমি আমার মূল প্রশ্নটিতে যেমনটি জিজ্ঞাসা করেছি ঠিক তেমনভাবে করা সম্ভব।

1) ক্লিকযোগ্য শব্দগুলিতে প্রয়োগ করা কাস্টম বৈশিষ্ট্যগুলির সাথে একটি বিশিষ্ট স্ট্রিং তৈরি করুন। যেমন।

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

2) সেই স্ট্রিংটি প্রদর্শনের জন্য একটি ইউআইটিএক্সেক্সটভিউ তৈরি করুন এবং এটিতে একটি ইউআইটিএপজেস্টাররেকগনিজার যুক্ত করুন। তারপরে ট্যাপটি হ্যান্ডেল করুন:

- (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);

    }
}

এত সহজ যখন আপনি জানেন কিভাবে!


আইওএস 6 এ আপনি কীভাবে এটি সমাধান করবেন? আপনি কি এই প্রশ্নটি একবার দেখে নিতে পারেন? stackoverflow.com/questions/19837522/...
Steaphann

প্রকৃতপক্ষে ক্যারেক্টিস্ট ইনডেক্সফরপয়েন্ট: ইনটেক্সটকন্টেইনার: ভগ্নাংশআফডেসটেন্সবিটুইনইনসারেশনপয়েন্টগুলি আইওএস on এ উপলব্ধ, তাই আমি মনে করি এটি কাজ করা উচিত। আমাদের জানতে দাও! উদাহরণস্বরূপ এই প্রকল্পটি দেখুন: github.com/laevandus/NSTextFieldHyperlinks/blob/master/…
টারেমস

ডকুমেন্টেশন বলে যে এটি কেবল আইওএস 7 বা তার পরে পাওয়া যাবে :)
স্টিফান

1
অস্ত্রোপচার. আমি নিজেকে ম্যাক ওএসের সাথে গুলিয়ে ফেলছিলাম! এটি কেবল আইওএস 7।
টারেমস

এটি আপনার কাজ করার মতো মনে হয় না, যখন আপনি বাছাইযোগ্য ইউআইটিএক্সেক্সটভিউ পাবেন
পল ব্রেউকজেনস্কি

64

সুইফ্টের সাথে বিশিষ্ট পাঠ্যে ট্যাপগুলি সনাক্ত করা

কখনও কখনও নতুনদের জন্য কীভাবে জিনিসগুলি সেট আপ করা যায় তা জানার জন্য কিছুটা কঠিন (এটি যাইহোক আমার পক্ষে ছিল), তাই এই উদাহরণটি একটু পরিপূর্ণ।

UITextViewআপনার প্রকল্পে একটি যুক্ত করুন ।

নালী

নামের সাথে একটি আউটলেট দিয়ে UITextViewএর ViewControllerসাথে সংযুক্ত করুন textView

কাস্টম বৈশিষ্ট্য

আমরা একটি এক্সটেনশন করে একটি কাস্টম অ্যাট্রিবিউট তৈরি করতে যাচ্ছি ।

দ্রষ্টব্য: এই পদক্ষেপটি প্রযুক্তিগতভাবে alচ্ছিক, তবে আপনি যদি এটি না করেন তবে আপনার একটি স্ট্যান্ডার্ড বৈশিষ্ট্য পছন্দ হিসাবে পরবর্তী অংশে কোডটি সম্পাদনা করতে হবে NSAttributedString.Key.foregroundColor। একটি কাস্টম অ্যাট্রিবিউট ব্যবহার করার সুবিধা হ'ল বৈশিষ্ট্যযুক্ত পাঠ্য সীমাতে আপনি কোন মানগুলি সংরক্ষণ করতে চান তা আপনি নির্ধারণ করতে পারেন।

ফাইল> নতুন> ফাইল ...> আইওএস> উত্স> সুইফট ফাইল সহ একটি নতুন সুইফ্ট ফাইল যুক্ত করুন । আপনি যা বলতে চান এটি কল করতে পারেন। আমি আমার এনএসএট্রিবিউটেড স্ট্রিংকি + কাস্টমঅ্যাট্রিবিউট.সুইফ্ট কল করছি ।

নিম্নলিখিত কোডে আটকান:

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
  • পূর্বে পাঠ্য দর্শনটি সম্পাদনাযোগ্য বা নির্বাচনের যোগ্য হতে পারে না, তবে সুইফট ৪.২-এর জন্য আমার আপডেট করা উত্তরে এটি নির্বাচিত কিনা তা নির্বিশেষে এটি ঠিকঠাক কাজ করছে বলে মনে হচ্ছে।

আরও অধ্যয়ন

এই উত্তরটি এই প্রশ্নের বেশ কয়েকটি অন্যান্য উত্তরের ভিত্তিতে ছিল। এগুলি ছাড়াও, আরও দেখুন


এর myTextView.textStorageপরিবর্তে ব্যবহার করুন myTextView.attributedText.string
ফাতিহিলিজহান

আইওএস 9-এ ট্যাপ অঙ্গভঙ্গির মাধ্যমে ট্যাপ সনাক্তকরণ ক্রমাগত ট্যাপগুলির জন্য কাজ করে না। কোন আপডেট আছে?
ধীররাজ জামি

1
@ ওয়াকাসমাহমুদ, আমি এই ইস্যুটির জন্য একটি নতুন প্রশ্ন শুরু করেছি । আপনি এটি তারকাচিহ্নিত করতে পারেন এবং কোনও উত্তরের জন্য পরে আবার পরীক্ষা করতে পারেন। এই প্রশ্নটি সম্পাদন করতে নির্দ্বিধায় বা আরও কিছু প্রাসঙ্গিক বিবরণ থাকলে মন্তব্য যুক্ত করুন।
সুরগাচ

1
@ ডিজিজ আমি প্রতিবার আমার টেক্সটভিউয়ের শেষে অন্য "" খালি স্ট্রিং যুক্ত করে সমস্যার সমাধান করি। এইভাবে আপনার শেষ শব্দের পরে সনাক্তকরণ বন্ধ হয়ে যায়। আশা করি এটি সহায়তা করে
পুলহলজুনকি

1
একাধিক ট্যাপের সাথে নিখুঁতভাবে কাজ করে, এটি প্রমাণ করার জন্য আমি কেবল একটি ছোট্ট রুটিন রেখেছি: যদি ক্যারেক্টিস্ট ইনডেক্স <12 {টেক্সটভিউ.টেক্সট कलোর = ইউআইসিওলর.মজেন্টা} অন্য {টেক্সটভিউ.টেক্সটকালার = ইউআইসিওলর.ব্লিউ} সত্যিই পরিষ্কার এবং সহজ কোড
জেরেমি অ্যান্ড্রুজ

32

এটি একটি হালকা পরিবর্তিত সংস্করণ @ নীচের টুইটটি ছাড়া আমি 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

    }
}

পাঠ্য ভিউ.অ্যাট্রিবিউটেডটেক্সটে একই সমস্যা ছিল! আপনাকে পাঠ্য ভিউ.টেক্সটসস্টোরেজ ইঙ্গিতটির জন্য ধন্যবাদ!
কাই বার্গার্ড্ট

আইওএস 9-এ ট্যাপ অঙ্গভঙ্গির মাধ্যমে ট্যাপ সনাক্তকরণ ক্রমাগত ট্যাপগুলির জন্য কাজ করে না।
ধীররাজ জামি

25

কাস্টম লিঙ্ক তৈরি করা এবং আপনি ট্যাপে যা চান তা করা আইওএস-এর মাধ্যমে খুব সহজ হয়ে গেছে Ray রে রেন্ডারলিচের খুব ভাল উদাহরণ রয়েছে


এটি তাদের ধারক দৃশ্যের তুলনায় স্ট্রিং অবস্থানগুলি গণনা করার চেষ্টা করার চেয়ে অনেক ক্লিনার সমাধান।
ক্রিস সি

2
সমস্যাটি হচ্ছে টেক্সটভিউয়ের বাছাইযোগ্য হওয়া দরকার এবং আমি এই আচরণটি চাই না।
থমস কলমন

@ ThomásC। আইবিয়ের UITextViewমাধ্যমে সেগুলি সনাক্ত করার জন্য যখন আমি এটি সেট করেছিলাম তখনও কেন আমার লিঙ্কগুলি সনাক্ত করা হচ্ছে না তার নির্দেশকের জন্য +1 । (আমি এটি অনির্বাচ্যও করেছিলাম)
কেদার পরানজপে

13

ডাব্লুডাব্লুডিসি 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:
}

ধন্যবাদ! আমি ডাব্লুডাব্লুডিসি ভিডিওটিও দেখব।
টারেমস

@ সুরগ "টেক্সট কিটের সাথে উন্নত পাঠ্য বিন্যাস এবং প্রভাব"।
শ্মিড্ট

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
  }

}

আপনার ইউআরএলটি ট্যাপ করা হয়েছে এবং বিবৃতিটির বাইরে if URL.scheme == "cs"এবং return trueবাইরে অন্য কোনও ইউআরএল ছিল না তা পরীক্ষা করা উচিত ifযাতে UITextViewটেপযুক্ত সাধারণ https://লিঙ্কগুলি পরিচালনা করতে পারে
ড্যানিয়েল স্টর্ম

আমি এটি করেছি এবং এটি আইফোন 6 এবং 6+ এ যুক্তিসঙ্গতভাবে ভাল কাজ করেছে তবে আইফোন 5 এ মোটেই কাজ করেনি above উপরে সুরগ সমাধান সমাধানে গিয়েছিলেন, যা কেবল কাজ করে। আইফোন 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 প্রতিনিধি পদ্ধতির সাহায্যে ক্রিয়াটি ধরতে পারেন o সুতরাং নিশ্চিত করুন যে আপনি প্রতিনিধিটি সঠিকভাবে সেট করেছেন।

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
    }

বুদ্ধিমানের মতো আপনি আপনার প্রয়োজনীয়তা অনুযায়ী যে কোনও ক্রিয়া সম্পাদন করতে পারেন।

চিয়ার্স !!


ধন্যবাদ! তুমি আমার দিন বাঁচাও!
ডিমিহ

4

এটি দিয়ে এটি করা সম্ভব characterIndexForPoint:inTextContainer:fractionOfDistanceBetweenInsertionPoints:। এটি আপনি চেয়েছিলেন কিছুটা আলাদাভাবে কাজ করবে - আপনি যদি টেপযুক্ত অক্ষরটি যাদু শব্দের সাথে সম্পর্কিত হয় তবে আপনাকে পরীক্ষা করতে হবে । তবে এটি জটিল হওয়া উচিত নয়।

বিটিডাব্লু আমি ডাব্লুডাব্লুডিসি 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

এটি একটি সংক্ষিপ্ত লিঙ্কের সাথে ঠিকঠাক কাজ করতে পারে, একটি পাঠ্যদর্শনটিতে মাল্টিলিংক। এটি আইওএস 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;
}

আইওএস 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
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.