Question

Est-il possible d'effectuer une action personnalisée lorsque la liaison téléphonique autodétectée contact utilisateur dans UITextView. S'il vous plaît ne pas conseiller à utiliser UIWebView à la place.

Et s'il vous plaît ne répétez pas seulement du texte à partir des classes de pomme référence  - certes, je l'ai déjà lu

.

Merci.

Était-ce utile?

La solution

Mise à jour: De ,

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

De et iOS 7 plus tard UITextView a le délégué méthode:

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

pour intercepter les clics vers des liens. Et c'est la meilleure façon de le faire.

et plus tôt une belle façon faire est par le sous-classement UIApplication et écrasez les -(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

Vous devrez implémenter openURL: dans votre délégué.

Maintenant, pour que l'application commence par votre nouvelle sous-classe de UIApplication, recherchez le fichier main.m dans votre projet. Dans ce petit fichier qui Bootstraps votre application, il y a habituellement cette ligne:

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

Le troisième paramètre est le nom de la classe pour votre application. Ainsi, en remplaçant cette ligne:

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

a fait l'affaire pour moi.

Autres conseils

Dans iOS 7 ou version ultérieure

Vous pouvez utiliser le délégué UITextView suivant Méthode:

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

Le point de vue du texte appelle cette méthode si les robinets utilisateur ou long appuie sur le lien URL. La mise en œuvre de cette méthode est facultative. Par défaut, l'affichage de texte ouvre l'application responsable de la gestion du type d'URL et passe l'URL. Vous pouvez utiliser cette méthode pour déclencher une autre action, comme l'affichage du contenu Web à l'URL dans une vue Web dans l'application en cours.

Important:

  

Liens dans les vues de texte ne sont interactifs si l'affichage du texte est   sélectionnable mais non modifiable. Autrement dit, si la valeur de la UITextView   la propriété de sélection est OUI et la propriété est isEditable NO.

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

ou si la cible est> = IOS 10

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

Version Swift:

Votre configuration standard UITextView devrait ressembler à quelque chose comme ça, ne pas oublier le délégué et 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)

Après la fin de votre classe ajouter cette pièce:

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

Avec Swift 5 et iOS 12, vous pouvez utiliser l'un des trois modèles suivants afin d'interagir avec des liens dans un UITextView.


# 1. En utilisant propriété UITextView dataDetectorTypes.

La façon la plus simple d'interagir avec les numéros de téléphone, adresses ou urls dans un UITextView est d'utiliser la propriété dataDetectorTypes. Le code exemple ci-dessous montre comment le mettre en œuvre. Avec ce code, lorsque l'utilisateur tape sur le numéro de téléphone, un UIAlertController apparaît.

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. En utilisant la méthode de UITextViewDelegate textView(_:shouldInteractWith:in:interaction:)

Si vous souhaitez effectuer une action personnalisée au lieu de faire un UIAlertController pop-up lorsque vous appuyez sur un numéro de téléphone en utilisant dataDetectorTypes, vous devez rendre votre UIViewController conforme à UITextViewDelegate protocole et mettre en œuvre textView(_:shouldInteractWith:in:interaction:). Le code ci-dessous montre comment mettre en œuvre:

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. En utilisant NSAttributedString et NSAttributedString.Key.link

Comme alternative, vous pouvez utiliser NSAttributedString et définir un URL pour son NSAttributedString.Key.link exemple de code attribut de ci-dessous montre une éventuelle mise en œuvre de celui-ci. Avec ce code, lorsque l'utilisateur tape sur la chaîne attribué, une UIAlertController apparaît.

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
    }

}

Je n'ai pas essayé moi-même, mais vous pouvez essayer de mettre en œuvre la méthode de application:handleOpenURL: dans votre application de déléguer -. Il ressemble par ce rappel passe toutes les demandes de openURL

Je ne sais pas comment vous intercepter la liaison de données détectée, ou quel type de fonction, vous devez exécuter. Mais vous pourriez être en mesure d'utiliser la méthode didBeginEditing TextField pour exécuter un test / scanner à travers le champ de texte si vous savez ce que vous cherchez for..such que la comparaison des chaînes de texte qui correspondent à ### - ### - Format ####, ou commencer par « www. » pour saisir ces champs, mais vous devez écrire un peu de code pour renifler à travers la chaîne TextFields, reconize ce que vous avez besoin, puis l'extraire pour l'utilisation de votre fonction. Je ne pense pas que ce serait si difficile, une fois que vous PRECISEE exactement ce que vous vouliez, puis se concentra votre filtre instruction if () vers le bas correspondant au motif très précis de ce que vous avez besoin.

De couse cela implique que l'utilisateur va toucher la zone de texte afin d'activer le didBeginEditing (). Si ce n'est pas le type d'interaction de l'utilisateur que vous recherchez, vous pouvez simplement utiliser une minuterie de déclenchement, qui commence ViewDidAppear () ou autre en fonction des besoins et passe par la chaîne TextFields, puis à la fin de l'exécution par la chaîne textfield méthodes que vous avez construit, vous tournez simplement la minuterie marche arrière.

application:handleOpenURL: est appelée quand une autre application ouvre votre application en ouvrant une URL avec un système de votre application prend en charge. Ce n'est pas appelé quand commence votre application ouvrir une URL.

Je pense que la seule façon de faire ce que veut Vladimir est d'utiliser un UIWebView au lieu d'un UITextView. Faites votre contrôleur vue de mettre en œuvre UIWebViewDelegate, définissez le délégué du UIWebView au contrôleur de vue, et dans le contrôleur de vue de mettre en œuvre webView:shouldStartLoadWithRequest:navigationType: pour ouvrir [request URL] en vue au lieu de quitter votre application et l'ouvrir dans Safari Mobile.

Swift 4:

1) Créer la classe suivante (sous-classé 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) Chaque fois que vous configurez votre textview, faites ceci:

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


Si vous utilisez story-board, assurez-vous que votre textview ressemble à ceci dans l'inspecteur de l'identité de volet droit:
entrer la description d'image ici


Le tour est joué! Maintenant, vous obtenez le lien tap immédiatement au lieu de lorsque l'URL shouldInteractWith méthode URL

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top