Pregunta

¿Es posible realizar una acción personalizada cuando el usuario toque autodetectado enlace de teléfono en UITextView. Por favor, no consejos para usar UIWebView lugar.

Y por favor, el texto no sólo la repetición de la referencia clases de manzana  -. Ciertamente yo ya lo he leído

Gracias.

¿Fue útil?

Solución

Actualización: Desde ,

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

y posteriores UITextView tiene el delegado método:

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

para interceptar los clics a enlaces. Y esta es la mejor manera de hacerlo.

En y anteriormente una buena manera de hacer esto es creando una subclase UIApplication y sobrescribir el -(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

Usted tendrá que aplicar openURL: en su delegado.

Ahora, para tener el inicio de la aplicación con su nueva subclase de UIApplication, localizar el main.m archivo en el proyecto. En este pequeño archivo que su aplicación sin ayuda de nadie, por lo general hay esta línea:

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

El tercer parámetro es el nombre de la clase para su aplicación. Por lo tanto, la sustitución de esta línea para:

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

Esto hizo el truco para mí.

Otros consejos

En iOS 7 o posterior

Se puede utilizar el siguiente UITextView delegado Método:

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

La vista de texto llama a este método si los grifos de usuario o de largo prensas el enlace URL. La implementación de este método es opcional. Por defecto, la vista de texto se abre la aplicación responsable de manejar el tipo de URL y lo pasa la URL. Puede utilizar este método para desencadenar una acción alternativa, por ejemplo, mostrar el contenido web en la dirección URL en una vista web dentro de la aplicación actual.

Importante:

  

Los enlaces en las vistas de texto son interactivos sólo si el texto es vista   seleccionable pero no editable. Es decir, si el valor de la UITextView   la propiedad seleccionable es YES y la propiedad isEditable es NO.

Para 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 si el objetivo es> = IOS 10

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

versión Swift:

La configuración UITextView estándar debe ser algo como esto, no se olvide el delegado y 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)

Después de que termine su clase añaden esta pieza:

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 Swift 5 y el IOS 12, puede utilizar uno de los tres siguientes patrones con el fin de interactuar con los eslabones de una UITextView.


# 1. El uso de UITextView dataDetectorTypes propiedad.

La forma más sencilla de interactuar con los números de teléfono, direcciones URL o direcciones en un UITextView es utilizar la propiedad dataDetectorTypes. El código de ejemplo siguiente muestra cómo ponerlo en práctica. Con este código, cuando los grifos de usuario en el número de teléfono, un UIAlertController aparece.

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. El uso de UITextViewDelegate textView(_:shouldInteractWith:in:interaction:) método

Si desea realizar alguna acción personalizada en lugar de hacer una UIAlertController pop-up al tocar en un número de teléfono durante el uso de dataDetectorTypes, usted tiene que hacer su UIViewController conforme con el protocolo UITextViewDelegate e implementar textView(_:shouldInteractWith:in:interaction:). El código siguiente muestra cómo ponerlo en práctica:

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. Utilizando NSAttributedString y NSAttributedString.Key.link

Como alternativa, se puede utilizar NSAttributedString y establecer un URL por su NSAttributedString.Key.link attribute.The código de ejemplo siguiente muestra una posible implementación de la misma. Con este código, cuando los grifos de usuario en la cadena con atributos, un UIAlertController aparece.

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
    }

}

no he probado yo mismo, pero se puede tratar de poner en práctica el método application:handleOpenURL: en su aplicación delegue - parece que todo pase a través de esta solicitud de devolución de llamada openURL

.

No está seguro de cómo le interceptar el enlace de datos detectada, o qué tipo de función que necesita para funcionar. Sin embargo, es posible que pueda utilizar el método didBeginEditing TextField para ejecutar una prueba / escaneo a través del campo de texto si usted sabe lo que busca for..such como la comparación de cadenas de texto que se encuentran ### - ### - #### de formato, o comenzar con "www." para agarrar esos campos, pero que tendría que escribir un poco de código de aspiración a través de la cadena de campos de texto, reconize lo que necesita, y luego extraerlo para el uso de su función. No creo que esto sería tan difícil, una vez que enangostado abajo de exactamente qué es lo que quería y luego centras sus filtros instrucción IF () a la coincidencia de patrones muy específicos de lo que sea necesario.

De couse esto implica que el usuario va a tocar el cuadro de texto con el fin de activar el didBeginEditing (). Si ese no es el tipo de interacción con el usuario a quien estabas buscando sólo podría utilizar un disparador del temporizador, que comienza el ViewDidAppear () u otra según la necesidad y se ejecuta a través de la cadena de campos de texto, a continuación, al final de ejecutar a través de la cadena de campo de texto métodos que usted construyó, que a su vez sólo la parte de atrás del temporizador apagado.

application:handleOpenURL: es llamada cuando se abre otra aplicación su aplicación mediante la apertura de una URL con un esquema de sus soportes de aplicaciones. No se llama cuando la aplicación se inicia la apertura de una URL.

Creo que la única manera de hacer lo que Vladimir quiere es utilizar un UIWebView en lugar de un UITextView. Asegúrese de que su controlador de vista implementar UIWebViewDelegate, establecer el delegado del UIWebView al controlador de vista, y en el controlador de vista aplicar webView:shouldStartLoadWithRequest:navigationType: a [request URL] abierta en una vista en lugar de dejar su aplicación y abrirla en Mobile Safari.

Swift 4:

1) crear la clase siguiente (subclase 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) Siempre que configura su TextView, hacer esto:

//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 está utilizando guión gráfico, asegúrese de que sus miradas TextView como esta en la derecha inspector de identidad panel:
introducir descripción de la imagen aquí


Voila! Ahora usted tiene la llave de enlace inmediatamente en lugar de cuando el método de URL shouldInteractWith URL

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top