UITextView में लिंक पर क्लिक कैसे करें?


101

जब उपयोगकर्ता UITextView में स्वतः-लिंक किए गए फ़ोन लिंक को स्पर्श करता है, तो क्या कस्टम क्रिया करना संभव है। कृपया इसके बजाय UIWebView का उपयोग करने की सलाह न दें।

और कृपया सेब वर्गों के संदर्भ से केवल पाठ को न दोहराएं - निश्चित रूप से मैं इसे पहले ही पढ़ चुका हूं।

धन्यवाद।

जवाबों:


144

अपडेट: से ,

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction;

से और बाद UITextViewमें प्रतिनिधि विधि है:

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange *NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");*

लिंक पर क्लिक को रोकने के लिए। और इसे करने का यह सबसे अच्छा तरीका है।

के लिये और पहले ऐसा करने का एक अच्छा तरीका उपवर्ग UIApplicationऔर अधिलेखित करने से है-(BOOL)openURL:(NSURL *)url

@interface MyApplication : UIApplication {

}

@end

@implementation MyApplication


-(BOOL)openURL:(NSURL *)url{
    if  ([self.delegate openURL:url])
         return YES;
    else
         return [super openURL:url];
}
@end

आपको openURL:अपने प्रतिनिधि में लागू करने की आवश्यकता होगी ।

अब, एप्लिकेशन को अपने नए उपवर्ग के साथ शुरू करने के लिए UIApplication, अपने प्रोजेक्ट में फ़ाइल main.m का पता लगाएं। आपके एप्लिकेशन को बूट करने वाली इस छोटी फ़ाइल में, आमतौर पर यह रेखा होती है:

int retVal = UIApplicationMain(argc, argv, nil, nil);

तीसरा पैरामीटर आपके आवेदन के लिए वर्ग का नाम है। इसलिए, इस पंक्ति को इसके लिए प्रतिस्थापित करें:

int retVal = UIApplicationMain(argc, argv, @"MyApplication", nil);

इसने मेरे लिए चाल चली।


आखिरी असली जवाब में! सरल और शांत विचार। धन्यवाद, यह काम करता है। यह बहुत समय पहले था, इसलिए मैं इसके बिना पहले से ही प्रबंधित हूं। फिर भी भविष्य में मदद मिल सकती है। छोटे सुधार हालांकि, शाखा में सुपर से परिणाम लौटाया जाना चाहिए: वापसी [सुपर ओपनुरल: यूआरएल];
व्लादिमीर

2
आप UIApplicationओगर्ल कार्यान्वयन को श्रेणीबद्ध और प्रतिस्थापित भी कर सकते हैं । हालांकि इस तरह यह मूल कार्यान्वयन को संदर्भित करने के लिए मुश्किल (लेकिन असंभव नहीं) है।
mxcl

1
FYI करें - मैंने GitHub पर एक BrowserViewController पोस्ट किया है जो इसे पूरी तरह से लागू करता है, साथ ही साथ एक UIWebView के भीतर से क्लिक किए गए समर्थन लिंक: github.com/nbuggia/Browser-View-Content.coiPhone-
नाथन बुगिया

3
यह केवल वेब लिंक के लिए काम करता है, न कि ऑटोफोरमैटेड फोन नंबरों के लिए।
अज़देव

मैं किस विधि से अपने आवेदन के प्रतिनिधि को निर्धारित कर सकता हूं?
रतिसिम्ह

50

IOS 7 या बाद के संस्करण में

आप निम्नलिखित UITextView प्रतिनिधि विधि का उपयोग कर सकते हैं:

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange

यदि उपयोगकर्ता टैप करता है या URL लिंक को लंबे समय तक दबाता है, तो पाठ दृश्य इस विधि को कॉल करता है। इस पद्धति का कार्यान्वयन वैकल्पिक है। डिफ़ॉल्ट रूप से, पाठ दृश्य URL प्रकार को संभालने के लिए जिम्मेदार एप्लिकेशन खोलता है और इसे URL पास करता है। आप वैकल्पिक पद्धति को ट्रिगर करने के लिए इस पद्धति का उपयोग कर सकते हैं, जैसे कि वर्तमान एप्लिकेशन के भीतर वेब दृश्य में URL पर वेब सामग्री प्रदर्शित करना।

जरूरी:

पाठ दृश्य में लिंक केवल तभी इंटरेक्टिव होते हैं, जब पाठ दृश्य चयन करने योग्य, लेकिन अप्राप्य हो। यही है, अगर UITextView का चयन करने योग्य संपत्ति YES है और isEditable संपत्ति नहीं है।


मुझे खुशी है कि उन्होंने इसे UITextViewDelegate में जोड़ा।
15:27 बजे fsaint

UIWebViewयदि आप कुछ अन्य पाठ को लिंक बनाना चाहते हैं तो दुर्भाग्यवश आप अभी भी इसका उपयोग करेंगे और URL ही नहीं। <a>टैग अब भी उस स्थिति में जाने के लिए सबसे अच्छा तरीका है।
MLQ

यदि अन्य लोग इसे देखते हैं, तो आप अब किसी अन्य पाठ का लिंक बना सकते हैं।
योजनाबद्ध

10

स्विफ्ट 3 के लिए

textView.delegate = self

extension MyTextView: UITextViewDelegate {

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {

        GCITracking.sharedInstance.track(externalLink: URL)
        return true
    }
}

या यदि लक्ष्य है> = IOS 10

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool

7

स्विफ्ट 5 और आईओएस 12 के साथ, आप एक में लिंक के साथ बातचीत करने के लिए तीन में से एक पैटर्न का उपयोग कर सकते हैं UITextView


# 1। का उपयोग करते हुए UITextViewकी dataDetectorTypesसंपत्ति।

संपत्ति UITextViewका उपयोग करने के लिए एक में फोन नंबर, यूआरएल या पते के साथ बातचीत करने का सबसे सरल तरीका है dataDetectorTypes। नीचे दिया गया नमूना कोड दिखाता है कि इसे कैसे लागू किया जाए। इस कोड के साथ, जब उपयोगकर्ता फ़ोन नंबर पर टैप करता है, तो एक UIAlertControllerपॉप अप होता है।

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = UITextView()
        textView.text = "Phone number: +33687654321"
        textView.isUserInteractionEnabled = true
        textView.isEditable = false
        textView.isSelectable = true
        textView.dataDetectorTypes = [.phoneNumber]
        textView.isScrollEnabled = false

        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
    }

}

# 2। का उपयोग करते हुए UITextViewDelegateकी textView(_:shouldInteractWith:in:interaction:)विधि

यदि आप UIAlertControllerउपयोग करते समय फ़ोन नंबर पर टैप करते समय पॉप अप करने के बजाय कुछ कस्टम क्रिया करना चाहते हैं dataDetectorTypes, तो आपको प्रोटोकॉल और कार्यान्वयन के लिए अपना UIViewControllerअनुरूप बनाना होगा । नीचे दिए गए कोड से पता चलता है कि इसे कैसे लागू किया जाए:UITextViewDelegatetextView(_:shouldInteractWith:in:interaction:)

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = UITextView()
        textView.delegate = self
        textView.text = "Phone number: +33687654321"
        textView.isUserInteractionEnabled = true
        textView.isEditable = false
        textView.isSelectable = true
        textView.dataDetectorTypes = [.phoneNumber]
        textView.isScrollEnabled = false

        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
    }

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        /* perform your own custom actions here */
        print(URL) // prints: "tel:+33687654321"

        return false // return true if you also want UIAlertController to pop up
    }

}

# 3। का उपयोग कर NSAttributedStringऔरNSAttributedString.Key.link

एक विकल्प के रूप में, आप इसकी विशेषता के लिए उपयोग NSAttributedStringऔर सेट कर सकते हैं । नीचे दिया गया नमूना कोड URLइसका NSAttributedString.Key.linkएक संभावित कार्यान्वयन दिखाता है। इस कोड के साथ, जब उपयोगकर्ता जिम्मेदार स्ट्रिंग पर टैप करता है, तो एक UIAlertControllerपॉप अप होता है।

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let attributedString = NSMutableAttributedString(string: "Contact: ")
        let phoneUrl = NSURL(string: "tel:+33687654321")! // "telprompt://+33687654321" also works
        let attributes = [NSAttributedString.Key.link: phoneUrl]
        let phoneAttributedString = NSAttributedString(string: "phone number", attributes: attributes)
        attributedString.append(phoneAttributedString)

        let textView = UITextView()
        textView.attributedText = attributedString
        textView.isUserInteractionEnabled = true
        textView.isEditable = false
        textView.isSelectable = true
        textView.isScrollEnabled = false

        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
    }

}

6

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

आपके मानक UITextView सेटअप को कुछ इस तरह से देखना चाहिए, डेलीगेट और डेटाटेक्टरटेप्स को न भूलें।

var textView = UITextView(x: 10, y: 10, width: CardWidth - 20, height: placeholderHeight) //This is my custom initializer
textView.text = "dsfadsaf www.google.com"
textView.selectable = true
textView.dataDetectorTypes = UIDataDetectorTypes.Link
textView.delegate = self
addSubview(textView)

आपकी कक्षा समाप्त होने के बाद इस टुकड़े को जोड़ें:

class myVC: UIViewController {
    //viewdidload and other stuff here
}

extension MainCard: UITextViewDelegate {
    func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
        //Do your stuff over here
        var webViewController = SVModalWebViewController(URL: URL)
        view.presentViewController(webViewController, animated: true, completion: nil)
        return false
    }
}

1

स्विफ्ट 4:

1) निम्न वर्ग बनाएँ (उपवर्गित उपखंड):

import Foundation

protocol QuickDetectLinkTextViewDelegate: class {
    func tappedLink()
}

class QuickDetectLinkTextView: UITextView {

    var linkDetectDelegate: QuickDetectLinkTextViewDelegate?

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

    }

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

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let glyphIndex: Int? = layoutManager.glyphIndex(for: point, in: textContainer, fractionOfDistanceThroughGlyph: nil)
        let index: Int? = layoutManager.characterIndexForGlyph(at: glyphIndex ?? 0)
        if let characterIndex = index {
            if characterIndex < textStorage.length {
                if textStorage.attribute(NSLinkAttributeName, at: characterIndex, effectiveRange: nil) != nil {
                    linkDetectDelegate?.tappedLink()
                    return self
                }
            }
        }

        return nil
    }
}


2) जहां भी आपने अपना टेक्स्टव्यू सेट किया है, यह करें:

//init, viewDidLoad, etc
textView.linkDetectDelegate = self

//outlet
@IBOutlet weak var textView: QuickDetectLinkTextView!

//change ClassName to your class
extension ClassName: QuickDetectLinkTextViewDelegate {
    func tappedLink() {
        print("Tapped link, do something")
    }
}


यदि आप स्टोरीबोर्ड का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आपका टेक्स्टव्यू सही फलक पहचान निरीक्षक में ऐसा दिखता है:
यहां छवि विवरण दर्ज करें



देखा! अब आपको URL के InInactactWith URL विधि के बजाय तुरंत लिंक टैप करना होगा


यह भी: यदि आप चाहते हैं कि url को संभाला नहीं जाए, तो बस झूठी वापसी करने के लिए InInactactWith तरीका सेट करें
Josh O'Connor

लगता है कि यह मुद्दों का एक गुच्छा है, जैसे कि क्या होता है जब आप एक लिंक टैप नहीं करते हैं। Ie मुझे नहीं लगता कि पाठ दृश्य सामान्य रूप से अब और काम करेगा, क्योंकि नील वापस आ रहा है। लिंक को टैप करने पर चयन भी बदल जाएगा, क्योंकि उस स्थिति में, स्व वापस आ जाता है।
ड्रू मैककॉर्मैक

मेरे लिए महान काम करता है, आपको अपनी जरूरतों के लिए ऐसे मामलों को संभालने की जरूरत है
जोश ओ'कॉनर

कमजोर var linkDetectDelegate: QuickDetectLinkTextViewDelegate?
मासलोसा

मेरे लिए @vyachaslav नहीं, आप कुछ गलत कर रहे होंगे
जोश ओ'कॉनर

0

मैंने खुद कोशिश नहीं की है लेकिन आप application:handleOpenURL:अपने आवेदन प्रतिनिधि में विधि को लागू करने का प्रयास कर सकते हैं - ऐसा लगता है कि openURLइस कॉलबैक से सभी अनुरोध पास हो गए हैं।


0

निश्चित नहीं है कि आप पता लगाए गए डेटा लिंक को कैसे इंटरसेप्ट करेंगे, या आपको किस प्रकार के फ़ंक्शन को चलाने की आवश्यकता है। लेकिन यदि आप यह जानते हैं कि टेक्स्ट फ़ील्ड के माध्यम से टेस्ट / स्कैन करने के लिए didBeginEditing TextField विधि का उपयोग करने में सक्षम हो सकता है यदि आपको पता है कि आपकी तलाश क्या है .. तो ### - ### # ### प्रारूप से मिलने वाले टेक्स्ट स्ट्रिंग्स की तुलना करें। या "www।" से शुरू करें। उन फ़ील्ड्स को हथियाने के लिए, लेकिन आपको टेक्स्टफ़ील्ड्स स्ट्रिंग के माध्यम से सूँघने के लिए थोड़ा कोड लिखना होगा, जो आपको चाहिए उसे समेट लें, और फिर इसे अपने फ़ंक्शन के उपयोग के लिए निकालें। मुझे नहीं लगता कि यह मुश्किल होगा, एक बार जब आप यह चाहते हैं कि आप क्या चाहते हैं, तो आपने इसे कम कर दिया है और फिर अपने if () स्टेटमेंट को आप की जरूरत के बहुत विशिष्ट मिलान पैटर्न के लिए फ़िल्टर कर दिया है।

सीज़ ऑफ का यह अर्थ है कि उपयोगकर्ता टेक्स्ट बॉक्स को छूने के लिए जा रहा है ताकि डिबगाइन एडिटिंग () को सक्रिय किया जा सके। यदि वह उस प्रकार का उपयोगकर्ता इंटरैक्शन नहीं है जिसे आप देख रहे थे, तो आप केवल ट्रिगर टाइमर का उपयोग कर सकते हैं, जो कि ViewDidAppear () या आवश्यकता के आधार पर शुरू होता है और टेक्स्टफिल्ड्स स्ट्रिंग के माध्यम से चलता है, फिर आपके अंत में टेक्स्ट स्ट्रिंग के माध्यम से चलता है आपके द्वारा बनाए गए तरीके, आप सिर्फ टाइमर को बंद कर देते हैं।


0

application:handleOpenURL:उस समय कहा जाता है जब कोई दूसरा ऐप आपके द्वारा समर्थित किसी स्कीम के साथ URL खोलकर आपके ऐप को खोल देता है। यह तब नहीं कहा जाता है जब आपका ऐप एक URL खोलना शुरू करता है।

मुझे लगता है कि व्लादिमीर चाहता है कि यूआईटैक्सव्यू के बजाय UIWebView का उपयोग करने का एकमात्र तरीका है। अपने दृश्य नियंत्रक को UIWebViewDelegate कार्यान्वित करें, UIWebView के प्रतिनिधि को व्यू कंट्रोलर पर सेट करें, और व्यू कंट्रोलर में अपने ऐप को छोड़ने और मोबाइल सफारी में खोलने के बजाय एक दृश्य में webView:shouldStartLoadWithRequest:navigationType:खोलने के लिए कार्यान्वित करें [request URL]

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