Puis-je changer la couleur des liens détectés automatiquement sur UITextView?

115

J'avais un UITextViewqui détecte les numéros de téléphone et les liens, mais cela remplace mon fontColoret le change en blueColor. Existe-t-il un moyen de formater la couleur des liens détectés automatiquement ou dois-je essayer une version manuelle de cette fonction?

Leandro Alves
la source
Vérifiez cette réponse en utilisant une sous-vue privée-api UIWebDocumentView: stackoverflow.com/a/11745983/111277
situee

Réponses:

170

Sur iOS 7, vous pouvez définir tintColorle UITextView. Il affecte la couleur du lien ainsi que la ligne du curseur et la couleur du texte sélectionné.

iOS 7 a également ajouté une nouvelle propriété à UITextViewappelé linkTextAttributesqui semblerait vous permettre de contrôler entièrement le style de lien.

stonemonk
la source
2
J'ai donné plus d'explications dans cette réponse: stackoverflow.com/a/21027340/1202222
Tim Windsor Brown
Sur iOS 10.3, je n'ai pas pu remplacer le NSFontAttributeNameavec linkTextAttributes. J'ai dû spécifier manuellement la police dans la même plage que monNSLinkAttributeName
Heath Borders
37

Au lieu d'utiliser un UITextView, j'ai utilisé un UIWebView et activé les "liens de détection automatique". Pour changer la couleur du lien, il suffit de créer un CSS normal pour la balise.

J'ai utilisé quelque chose comme ça:

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
la source
13
Cela semble extrêmement hackish pour une tâche aussi simple.
yuikonnu
Je sais ... mais je ne connais pas de solution de contournement moins hackish. Apple devrait vraiment réfléchir à ces petits détails.
Leandro Alves
@Oscar eh bien, je pense que c'est moins hackish que ne répondent Alexanders. Encore fou qu'il n'y ait pas de propriété simple pour une fonctionnalité aussi fondamentale.
Andy
1
La question concerne la vue textuelle et non la vue Web!
Boris Gafurov
entièrement d'accord avec "asdasd". L'approche Web coûte très cher, ils voient combien de RAM elle utilise. pour une tâche aussi simple, utilisez textview et propriétés qu'Apple donne.
ingconti
37

Vous pouvez utiliser le UIAppearanceprotocole pour appliquer des modifications à toutes les vues de texte:

Swift 4.x:

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

Swift 3.x:

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

Swift 2.x:

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

Objectif c:

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

L'apparence pour UITextViewn'est pas documentée, mais fonctionne bien.

Gardez à l'esprit les UIAppearancenotes:

iOS applique des changements d'apparence lorsqu'une vue entre dans une fenêtre, cela ne change pas l'apparence d'une vue qui est déjà dans une fenêtre. Pour modifier l'apparence d'une vue qui se trouve actuellement dans une fenêtre, supprimez la vue de la hiérarchie des vues, puis remettez-la en place.

En d' autres termes: Appeler ce code dans init()ou init(coder:)méthodes vont changer l' interface utilisateur apparence de l' objet, mais d' appeler à loadView()ou viewDidLoad()de viewController ne sera pas .
Si vous souhaitez définir l'apparence de l'ensemble de l'application, application(_:didFinishLaunchingWithOptions:)c'est un bon endroit pour appeler un tel code.

Grubas
la source
Je préfère celle-ci à la réponse sélectionnée, car je souhaite utiliser une couleur différente pour la sélection du curseur / texte et des liens
Kevin R
C'est la meilleure réponse à jour.
yuzer
J'ai utilisé un UITextView et j'ai écrit le code ci-dessus dans viewdidload. mais lorsque j'écris un e-mail dans le champ de texte et que j'entre dans l'espace, la couleur ne change pas.
Raj Aggrawal
18

Le problème avec UITextView linkTextAttributesest qu'il s'applique à tous les liens détectés automatiquement. Que faire si vous souhaitez que différents liens aient des attributs différents?

Il s'avère qu'il y a une astuce: configurez les liens dans le cadre du texte attribué à la vue texte et définissez le linkTextAttributessur un dictionnaire vide .

Voici un exemple dans 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 = [:]
mat
la source
Ma chaîne est "Voulez-vous apprendre iOS?" Vous devriez visiter la meilleure source de tutoriels iOS gratuits! Vérification rapide bonjour google.com Attribuée 9826012345 Test de chaîne en cours ... "et l'attribut Lien par défaut est requis pour le lien Web et le numéro de mobile. Mais je souhaite créer un lien pour la partie chaîne" Voulez-vous apprendre iOS? "Dans une couleur différente with link..So self.tv.linkTextAttributes = [:] ne fonctionne que pour le lien personnalisé.
BalKrishan Yadav
14

Vous pouvez modifier la couleur du lien hypertexte dans un TextView comme suit:

Dans le fichier Nib, vous pouvez accéder à la fenêtre Propriétés et modifier la teinte en fonction de la couleur souhaitée.

ou vous pouvez également le faire par programme en utilisant le code ci-dessous

[YOURTEXTVIEW setTintColor:[UIColor whiteColor]];
Manju
la source
5

La couleur de la teinte peut également être effectuée dans le storyboard

entrez la description de l'image ici

Ryan Heitner
la source
3

J'ai trouvé en effet un autre moyen sans utiliser de vue Web mais gardez à l'esprit que cela utilise une API privée et peut être rejeté dans l'Appstore:

EDIT: Mon application a été approuvée par Apple bien que l'utilisation de l'API privée!

Déclarez d'abord une catégorie sur UITextView avec les méthodes

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

Ils font juste ce qui suit:

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

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

Maintenant, écrivez une méthode pour les liens colorés:

- (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];
}

Il définit l'attribut de style avec une couleur spécifique sur tous les types de liens.

Les UITextViews sont rendus Webiview comme via des divs afin que vous puissiez même aller plus loin et colorer chaque type de lien séparément:

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

Le x-apple-data-detectors-type="link"est l'indicateur du type exact du lien

ÉDITER

Sur iOS7ce ne fonctionne plus. Dans iOS7, vous pouvez facilement changer la couleur du lien de UITextViews en définissant la couleur de teinte. Tu ne devrais pas appeler

- (id)contentAsHTMLString;

plus, vous obtiendrez une exception. À la place, procédez comme suit si vous souhaitez prendre en charge iOS 7 et les versions antérieures:

- (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];

}
}
Alexandre
la source
3

Réponse Swift 5

Sympa et simple

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

EDIT: Ne le faites pas avec UITextView, utilisez à la UIWebViewplace.

Vous devez créer une feuille de style pour cela. Définissez-y une classe avec la combinaison de couleurs dont vous avez besoin-

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

utilisez maintenant la classe 'headercopy' dans votre page html comme ceci-

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

cela affichera le numéro de téléphone dans la couleur dont vous avez besoin avec la fonctionnalité de clic.

Vaibhav Saran
la source
l'utilisation de vues Web est un mauvais style de programmation pour les applications natives.
ingconti
0

Ce code définira la couleur d'un numéro de téléphone sur un I-Phone mais annulera le lien d'appel automatique.

<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
la source
0

Voici comment je l'ai fait avec 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
la source