Procedimiento para interceptar haga clic en el enlace en UITextView?
-
23-09-2019 - |
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.
Solución
Actualización: Desde ios10 ,
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction;
iOS7 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 iOS6 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:
Voila! Ahora usted tiene la llave de enlace inmediatamente en lugar de cuando el método de URL shouldInteractWith URL