Domanda

E 'possibile eseguire l'azione personalizzata quando tocco utente rilevato automaticamente collegamento telefonico in UITextView. Si prega di non consiglio di utilizzare UIWebView invece.

E per favore non è sufficiente ripetere il testo da riferimento le classi di mele  - certamente ho già letto

.

Grazie.

È stato utile?

Soluzione

Aggiornamento: Da ,

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

e UITextView Più tardi ha il delegato metodo:

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

di intercettare i click al link. E questo è il modo migliore per farlo.

e in precedenza un bel modo per farlo è quello di sottoclasse UIApplication e sovrascrivendo il -(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

Sarà necessario implementare openURL: nel vostro delegato.

Ora, per avere avviare l'applicazione con la nuova sottoclasse di UIApplication, individuare il file main.m nel progetto. In questo piccolo file che bootstrap la vostra applicazione, di solito c'è questa linea:

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

Il terzo parametro è il nome della classe per l'applicazione. Quindi, in sostituzione di questa linea per:

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

Questo ha fatto il trucco per me.

Altri suggerimenti

In iOS 7 o versioni successive

È possibile utilizzare il seguente metodo UITextView delegato:

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

La vista testo chiama questo metodo se l'utente tocca o lungo preme sul link. L'attuazione di questo metodo è facoltativa. Per impostazione predefinita, la visualizzazione del testo apre l'applicazione responsabile per la gestione del tipo di URL e lo passa l'URL. È possibile utilizzare questo metodo per attivare un'azione alternativa, come ad esempio la visualizzazione del contenuto Web all'URL in una visualizzazione web all'interno dell'applicazione corrente.

Importante:

  

I collegamenti in vista di testo sono interattivi solo se la vista del testo è   selezionabile ma non modificabile. Cioè, se il valore della UITextView   la proprietà selezionabile è SI e la proprietà IsEditable è NO.

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 il target è> = IOS 10

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

Versione Swift:

La configurazione UITextView standard dovrebbe essere simile a questo, non dimenticate 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 classe finisce aggiungere 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
    }
}

Con la Swift 5 e iOS 12, è possibile utilizzare uno dei tre seguenti modelli al fine di interagire con i collegamenti in un UITextView.


# 1. Utilizzo proprietà UITextView di dataDetectorTypes.

Il modo più semplice per interagire con i numeri di telefono, indirizzi URL o in un UITextView è quello di utilizzare la proprietà dataDetectorTypes. Il codice di esempio seguente mostra come implementarlo. Con questo codice, quando l'utente tocca al telefono, un UIAlertController apre.

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. Utilizzando UITextViewDelegate di textView(_:shouldInteractWith:in:interaction:) metodo

Se si desidera eseguire una certa azione personalizzata invece di fare un UIAlertController pop-up quando si tocca un numero di telefono durante l'utilizzo dataDetectorTypes, dovete fare il vostro UIViewController conforme al protocollo UITextViewDelegate e implementare textView(_:shouldInteractWith:in:interaction:). Il codice seguente mostra come implementarlo:

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. Utilizzando NSAttributedString e NSAttributedString.Key.link

In alternativa, è possibile utilizzare NSAttributedString e impostare un URL per la sua NSAttributedString.Key.link attribute.The codice di esempio riportato di seguito mostra una possibile implementazione di esso. Con questo codice, quando utente tocca sulla corda attribuito un UIAlertController apre.

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
    }

}

Non ho provato io stesso, ma si può provare a implementare il metodo application:handleOpenURL: nella vostra applicazione delegato -. Sembra che tutte le richieste openURL passano attraverso questo callback

Non sei sicuro di come si dovrebbe intercettare il collegamento dati rilevati, o che tipo di funzione è necessario eseguire. Ma si può essere in grado di utilizzare il metodo didBeginEditing TextField per eseguire un test / eseguire la scansione attraverso il campo di testo se si sa che cosa il vostro cercando for..such come confrontando stringhe di testo che soddisfano ### - ### - #### formato, o iniziare con "www." per afferrare quei campi, ma si avrebbe bisogno di scrivere un po 'di codice per annusare attraverso la stringa textfields, reconize quello che ti serve, e quindi estrarre per l'uso del vostra funzione. Non credo che questo sarebbe stato così difficile, una volta che si ristretto giù esattamente che cosa è che si voleva e poi messo a fuoco la sua dichiarazione, se () filtra fino a molto specifico pattern matching di quello che avevi bisogno.

Di couse questo implica che l'utente sta per toccare la casella di testo al fine di attivare il didBeginEditing (). Se questo non è il tipo di interazione con l'utente che stavi cercando si potrebbe utilizzare un timer di attivazione, che inizia il viewDidAppear () o altro in base alle esigenze e attraversa la stringa di campi di testo, poi alla fine di che si esegue attraverso la stringa campo di testo metodi che è costruito, basta girare il timer marcia indietro.

application:handleOpenURL: viene chiamato quando si apre un altro app tuo app aprendo un URL con uno schema la vostra applicazione supporta. Non è chiamato quando la vostra applicazione inizia l'apertura di un URL.

Credo che l'unico modo per fare ciò che vuole Vladimir è quello di utilizzare un UIWebView invece di un UITextView. Fai la tua controller della vista implementare UIWebViewDelegate, impostare delegato del UIWebView al controller della vista, e nel controller di vista implementare webView:shouldStartLoadWithRequest:navigationType: per aprire [request URL] in vista, invece di rinunciare il vostro app e aprirlo in Safari Mobile.

Swift 4:

1) Creare la classe seguente (sottoclasse 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 si imposta il tuo TextView, fare 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 storyboard, assicurarsi che il proprio TextView si presenta così nel riquadro di destra identità ispettore:
entrare descrizione dell'immagine qui


Ecco! Ora si ottiene il rubinetto di collegamento immediatamente invece di quando il metodo URL shouldInteractWith URL

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top