Come intercettare fare clic sul collegamento in UITextView?

È ansible eseguire azioni personalizzate quando l’utente tocca il collegamento telefonico rilevato automaticamente in UITextView. Non raccomandare invece di utilizzare UIWebView.

E per favore non limitarti a ripetere il testo dal riferimento alle classi di mele – certamente l’ho già letto.

Grazie.

Aggiornamento: da ios10 ,

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

Da ios7 e successivi UITextView ha il metodo delegato:

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

intercettare i clic sui collegamenti. E questo è il modo migliore per farlo.

Per iOS6 e precedenti un buon modo per farlo consiste nel sottoclass UIApplication e nella sovrascrittura 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 

Dovrai implementare openURL: nel tuo delegato.

Ora, per far avviare l’applicazione con la nuova sottoclass di UIApplication , individuare il file main.m nel progetto. In questo file di piccole dimensioni che avvia automaticamente l’app, di solito c’è questa riga:

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

Il terzo parametro è il nome della class per la tua applicazione. Quindi, sostituendo questa linea per:

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

Questo ha fatto il trucco per me.

In iOS 7 o versioni successive

È ansible utilizzare il seguente metodo delegato UITextView:

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

La visualizzazione del testo chiama questo metodo se l’utente tocca o preme a lungo il link dell’URL. L’implementazione di questo metodo è facoltativa. Per impostazione predefinita, la visualizzazione del testo apre l’applicazione responsabile della gestione del tipo di URL e passa l’URL. È ansible utilizzare questo metodo per triggersre un’azione alternativa, ad esempio la visualizzazione del contenuto Web all’URL in una visualizzazione Web all’interno dell’applicazione corrente.

Importante:

I collegamenti nelle viste di testo sono interattivi solo se la vista testuale è selezionabile ma non modificabile. Cioè, se il valore di UITextView la proprietà selezionabile è SÌ e la proprietà isEditable è NO.

Versione rapida:

La tua configurazione standard di UITextView dovrebbe essere simile a questa, non dimenticare il delegato e dataDetectorTypes.

 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) 

Dopo la fine della lezione aggiungi questo pezzo:

 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 } } 

Per Swift 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 } } 

o se l’objective è> = IOS 10

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

Con Swift 3 e i0S 10, il modo più semplice per interagire con numeri di telefono, url o indirizzi in UITextView è utilizzare UIDataDetectorTypes . Il codice seguente mostra come visualizzare un numero di telefono in un UITextView modo che l’utente possa interagire con esso.

 import UIKit class ViewController: UIViewController { // Link this outlet to a UITextView in your Storyboard @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.text = "+33687654321" textView.isUserInteractionEnabled = true // default: true textView.isEditable = false // default: true textView.isSelectable = true // default: true textView.dataDetectorTypes = [.phoneNumber] } } 

Con questo codice, quando si fa clic sul numero di telefono, verrà UIAlertController un UIAlertController .


In alternativa, è ansible utilizzare NSAttributedString :

 import UIKit class ViewController: UIViewController { // Link this outlet to a UITextView in your Storyboard @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() let phoneUrl = NSURL(string: "tel:+33687654321")! // "telprompt://+33687654321" also works let attributes = [NSLinkAttributeName: phoneUrl] let attributedString = NSAttributedString(string: "phone number", attributes: attributes) textView.attributedText = attributedString textView.isUserInteractionEnabled = true // default: true textView.isEditable = false // default: true textView.isSelectable = true // default: true } } 

Con questo codice, quando si fa clic sulla stringa attribuita, verrà UIAlertController un UIAlertController .


Tuttavia, potresti voler eseguire alcune azioni personalizzate invece di far UIAlertController un UIAlertController quando fai clic su un numero di telefono. O potresti voler mantenere un UIAlertController per apparire ed eseguire la tua azione personalizzata nello stesso tempo.

In entrambi i casi, dovrai rendere UIViewController conforms al protocollo UITextViewDelegate e implementare textView(_:shouldInteractWith:in:interaction:) . Il codice qui sotto mostra come farlo.

 import UIKit class ViewController: UIViewController, UITextViewDelegate { // Link this outlet to a UITextView in your Storyboard @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self textView.text = "+33687654321" textView.isUserInteractionEnabled = true textView.isEditable = false textView.isSelectable = true textView.dataDetectorTypes = [.phoneNumber] } func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { /* perform your own custom actions here */ print(URL) return false // return true if you still want UIAlertController to pop up } } 

Con questo codice, quando si fa clic sul numero di telefono, non UIAlertController e si otterrà la seguente stampa nella console:

tel: +33687654321

Ho un contenuto dinamico nella visualizzazione del testo, che può contenere un collegamento. Il shouldInteractWithURL viene chiamato solo quando l’utente è premuto a lungo sul collegamento ma non chiama al touch del collegamento. Si prega di redirect se qualche amico ha riferimento ad esso.

Di seguito è riportato alcuni dei codice sniped.

 UITextView *ltextView = [[UITextView alloc] init]; [ltextView setScrollEnabled:YES]; [ltextView setDataDetectorTypes:UIDataDetectorTypeLink]; ltextView.selectable = YES; [ltextView setEditable:NO]; ltextView.userInteractionEnabled = YES; ltextView.delegate = (id)self; ltextView.delaysContentTouches = NO; [self.view addsubview:ltextview]; - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange{ [self.mActionDelegate userClickedOnImageLinkFromWebview:URL]; NSLog(@"urls is :- %@",URL); return FALSE; } 

Il metodo delegato sopra riportato non viene richiamato alla chiamata.

Saluti, Rohit Jankar

Swift 4:

1) Creare la seguente class (sottoclass UITextView):

 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) Ovunque tu imposti la tua textview, fai questo:

 //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") } } 

Se stai usando lo storyboard, assicurati che la tua vista del testo sia simile alla finestra di ispezione delle id quadro del pannello destro:
inserisci la descrizione dell'immagine qui

Ecco! Ora si ottiene immediatamente il collegamento tap invece di quando l'URL dovrebbe utilizzare il metodo URLInteractWith

Non l’ho provato da solo, ma puoi provare a implementare l’ application:handleOpenURL: metodo nel tuo delegato dell’applicazione: sembra che tutte openURL richieste openURL passino attraverso questo callback.

Non sei sicuro di come intercetterai il collegamento dati rilevato o quale tipo di funzione devi eseguire. Ma potresti essere in grado di utilizzare il metodo didBeginEditing TextField per eseguire un test / scansione attraverso il campo di testo se sai cosa stai cercando … come confrontare stringhe di testo che soddisfano il formato ### – ### – ####, o iniziare con “www.” per afferrare quei campi, ma avresti bisogno di scrivere un piccolo codice per annusare la stringa dei campi di testo, ricambiare ciò di cui hai bisogno e quindi estrarlo per l’uso della tua funzione. Non penso che sarebbe così difficile, una volta che hai ristretto esattamente ciò che volevi e poi hai focalizzato la tua dichiarazione if () sui filtri fino a uno schema di corrispondenza molto specifico di ciò che ti serviva.

Questo suggerisce che l’utente sta per toccare la casella di testo per triggersre il didBeginEditing (). Se questo non è il tipo di interazione dell’utente che stavi cercando, potresti semplicemente utilizzare un timer di triggerszione, che inizia su ViewDidAppear () o altro in base alle necessità e scorre attraverso la stringa di campi di testo, quindi alla fine esegui la stringa di testo metodi che hai creato, devi solo distriggersre il timer.

application:handleOpenURL: viene chiamato quando un’altra app apre la tua app aprendo un URL con uno schema supportato dalla tua app. Non viene chiamato quando la tua app inizia ad aprire un URL.

Penso che l’unico modo per fare ciò che vuole Vladimir sia utilizzare UIWebView invece di UITextView. Fai in modo che il tuo controller di visualizzazione implementa UIWebViewDelegate, imposta il delegato di UIWebView sul controller di visualizzazione e nel controller di visualizzazione implementa webView:shouldStartLoadWithRequest:navigationType: per aprire [request URL] in una vista invece di chiudere la tua app e aprirla in Mobile Safari.