¿Puedo cambiar el color de los enlaces detectados automáticamente en UITextView?

115

Tenía un UITextViewque detecta números de teléfono y enlaces, pero esto anula mi fontColory lo cambia a blueColor. ¿Hay alguna forma de formatear el color de los enlaces detectados automáticamente, o debería probar una versión manual de esta función?

Leandro Alves
fuente
Verifique esta respuesta usando una subvista de API privada UIWebDocumentView: stackoverflow.com/a/11745983/111277
situee

Respuestas:

170

En iOS 7 puede configurar tintColorel UITextView. Afecta al color del enlace, así como a la línea del cursor y al color del texto seleccionado.

iOS 7 también agregó una nueva propiedad a la UITextViewllamada linkTextAttributesque parecería permitirle controlar completamente el estilo del enlace.

monje de piedra
fuente
2
He dado más explicaciones en esta respuesta: stackoverflow.com/a/21027340/1202222
Tim Windsor Brown
En iOS 10.3, no pude anular NSFontAttributeNamecon linkTextAttributes. Tuve que especificar manualmente la fuente en el mismo rango que miNSLinkAttributeName
Heath Borders
37

En lugar de usar un UITextView, usé un UIWebView y habilité los "enlaces de detección automática". Para cambiar el color del enlace, acaba de crear un CSS normal para la etiqueta.

Usé algo como esto:

NSString * htmlString = [NSString stringWithFormat:@"<html><head><script> document.ontouchmove = function(event) { if (document.body.scrollHeight == document.body.clientHeight) event.preventDefault(); } </script><style type='text/css'>* { margin:0; padding:0; } p { color:black; font-family:Helvetica; font-size:14px; } a { color:#63B604; text-decoration:none; }</style></head><body><p>%@</p></body></html>", [update objectForKey:@"text"]];
webText.delegate = self;
[webText loadHTMLString:htmlString baseURL:nil];
Leandro Alves
fuente
13
Esto parece extremadamente complicado para una tarea tan simple.
Yuikonnu
Lo sé ... pero no conozco ninguna solución menos hacker. Apple realmente debería pensar en estos pequeños detalles.
Leandro Alves
@Oscar, bueno, creo que es menos hacker que la respuesta de Alexanders. Todavía es una locura que no haya una propiedad simple para una funcionalidad tan fundamental.
Andy
1
¡La pregunta es sobre textview, no webview!
Boris Gafurov
totalmente de acuerdo con "asdasd". El enfoque web es muy caro, para ver la cantidad de RAM que usa. para una tarea tan simple, use la vista de texto y las propiedades que ofrece Apple.
ingconti
37

Puedes usar UIAppearance protocolo para aplicar cambios a todas las vistas de texto:

Rápido 4.x:

UITextView.appearance().linkTextAttributes = [ .foregroundColor: UIColor.red ]

Swift 3.x:

UITextView.appearance().linkTextAttributes = [ NSForegroundColorAttributeName: UIColor.red ]

Rápido 2.x:

UITextView.appearance().linkTextAttributes = [ NSForegroundColorAttributeName: UIColor.redColor() ]

C objetivo:

[UITextView appearance].linkTextAttributes = @{ NSForegroundColorAttributeName : UIColor.redColor };

Apariencia para UITextView no está documentada, pero funciona bien.

Tenga en cuenta las UIAppearancenotas:

iOS aplica cambios de apariencia cuando una vista ingresa a una ventana, no cambia la apariencia de una vista que ya está en una ventana. Para cambiar la apariencia de una vista que se encuentra actualmente en una ventana, elimine la vista de la jerarquía de vistas y luego vuelva a colocarla.

En otras palabras: se llama a este código en init(), o init(coder:)métodos serán cambiar la apariencia de objetos de interfaz de usuario, pero llamar a loadView(), o viewDidLoad()de viewController no lo hará .
Si desea establecer la apariencia de toda la aplicación, application(_:didFinishLaunchingWithOptions:)es un buen lugar para llamar a dicho código.

Grubas
fuente
Prefiero esta a la respuesta seleccionada, ya que quiero usar un color diferente para la selección del cursor / texto y los enlaces
Kevin R
Ésta es la mejor y más actualizada respuesta.
Yuzer
He usado un UITextView y escribí el código anterior en viewdidload. pero cuando escribo un correo electrónico en el campo de texto e ingreso el espacio, el color no cambia.
Raj Aggrawal
18

El problema con UITextView linkTextAttributeses que se aplica a todos los enlaces detectados automáticamente. ¿Qué sucede si desea que diferentes enlaces tengan diferentes atributos?

Resulta que hay un truco: configure los enlaces como parte del texto atribuido de la vista de texto y establezca el linkTextAttributesen un diccionario vacío .

Aquí hay un ejemplo en iOS 11 / Swift 4:

// mas is the mutable attributed string we are forming...
// ... and we're going to use as the text view's `attributedText`
mas.append(NSAttributedString(string: "LINK", attributes: [
    NSAttributedStringKey.link : URL(string: "https://www.apple.com")!,
    NSAttributedStringKey.foregroundColor : UIColor.green,
    NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue
]))
// ...
self.tv.attributedText = mas
// this is the important thing:
self.tv.linkTextAttributes = [:]
mate
fuente
Mi cadena es "¿Quieres aprender iOS?" ¡Debería visitar la mejor fuente de tutoriales gratuitos de iOS! Comprobación rápida hola google.com Atribuido 9826012345 Pruebas de cadena en curso ... "y el atributo de vínculo predeterminado es obligatorio para el vínculo web y el número de teléfono móvil. Pero quiero crear un vínculo para la parte de cadena" ¿Quieres aprender iOS? "En un color diferente con enlace .. Así que self.tv.linkTextAttributes = [:] funciona solo para enlaces personalizados.
BalKrishan Yadav
14

Puede cambiar el color del hipervínculo en un TextView de la siguiente manera:

En el archivo Nib, puede ir a la ventana Propiedades y cambiar el Tinte al color que desee.

o también puede hacerlo programáticamente usando el siguiente código

[YOURTEXTVIEW setTintColor:[UIColor whiteColor]];
Manju
fuente
5

El color del tinte también se puede hacer en el guión gráfico.

ingrese la descripción de la imagen aquí

Ryan Heitner
fuente
3

De hecho, encontré otra forma sin usar una vista web, pero tenga en cuenta que esto usa una API privada y puede ser rechazada en la tienda de aplicaciones:

EDITAR: ¡ Mi aplicación fue aprobada por Apple aunque el uso de la API privada!

Primero declare una categoría en UITextView con los métodos

- (id)contentAsHTMLString;
- (void)setContentToHTMLString:(id)arg1;

Simplemente están haciendo lo siguiente:

- (id)contentAsHTMLString;
{
    return [super contentAsHTMLString];
}

- (void)setContentToHTMLString:(id)arg1;
{
    [super setContentToHTMLString:arg1];
}

Ahora escribe un método para enlaces coloridos:

- (void) colorfillLinks;
{
    NSString *contentString = [self.textViewCustomText contentAsHTMLString];
    contentString = [contentString stringByReplacingOccurrencesOfString:@"x-apple-data-detectors=\"true\""
                                         withString:@"x-apple-data-detectors=\"true\" style=\"color:white;\""];
    [self.textViewCustomText setContentToHTMLString:contentString];
}

Establece el atributo de estilo con un color específico en todo tipo de enlaces.

UITextViews se procesan en Webiview como a través de divs, por lo que incluso podría ir más allá y colorear cada tipo de enlace por separado:

<div><a href="http://www.apple.com" x-apple-data-detectors="true" style="color:white;" x-apple-data-detectors-type="link" x-apple-data-detectors-result="0">http://www.apple.com</a></div>

El x-apple-data-detectors-type="link"es el indicador del tipo exacto de enlace.

EDITAR

En iOS7esto ya no funciona. En iOS7, puede cambiar fácilmente el color del enlace de UITextViews configurando el color del tinte. No deberías llamar

- (id)contentAsHTMLString;

más, obtendrá una excepción. En su lugar, haga lo siguiente si desea admitir iOS 7 y versiones anteriores:

- (void) colorfillLinks;
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    self.tintColor = [UIColor colorWithRed:79.0/255.0
                                     green:168.0/255.0
                                      blue:224.0/255.0
                                     alpha:1.0];
} else if(![self isFirstResponder ]) {
    NSString *contentString = [self contentAsHTMLString];
    contentString = [contentString stringByReplacingOccurrencesOfString:@"x-apple-data-detectors=\"true\""
                                                             withString:@"x-apple-data-detectors=\"true\" style=\"color:#DDDDDE;\""];
    [self setContentToHTMLString:contentString];

}
}
Alejandro
fuente
3

Respuesta rápida 5

Agradable y simple

myTextView.linkTextAttributes = [.foregroundColor: UIColor.white]
Mark Wilson
fuente
0

EDITAR: No lo hagas con UITextView, usa UIWebViewen su lugar.

Necesitas hacer una hoja de estilo para eso. Defina una clase allí con la combinación de colores que necesita-

.headercopy {
 font-family: "Helvetica";
 font-size: 14px;
 line-height: 18px;
 font-weight:bold;
 color: #25526e;
}
a.headercopy:link {
 color:#ffffff;
 text-decoration:none;
}
a.headercopy:hover {
 color:#00759B;
 text-decoration:none;
}
a.headercopy:visited {
 color:#ffffff;
 text-decoration:none;
} 
a.headercopy:hover {
 color:#00759B;
 text-decoration:none;
}

ahora use la clase 'headercopy' en su página html como esta-

<b>Fax:</b><a href="tel:646.200.7535" class="headercopy"> 646-200-7535</a><br />

esto mostrará el número de teléfono en el color que necesita con la función de clic.

Vaibhav Saran
fuente
El uso de vistas web es un mal estilo de programación para aplicaciones nativas.
ingconti
0

Este código establecerá el color de un número de teléfono en un I-Phone pero anula el enlace de llamada automática.

<div><a href="#" x-apple-data-detectors="true" style="color:white;" x-apple-data-detectors-type="link" x-apple-data-detectors-result="0">p&nbsp;&nbsp;0232 963 959</a></div>
Mark Overton
fuente
0

Así es como lo hice usando Swift 5:

let attributedString = NSMutableAttributedString(string: myTextView.text ?? "")
myTextView.linkTextAttributes = [NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): UIColor.whiteColor] as [NSAttributedString.Key: Any]?
myTextView.attributedText = attributedString
Jaytrixz
fuente