Multiples couleurs sur un UILabel incluant plusieurs NSString
Bonjour,
J'utilise actuellement un label qui comprend 3 NSString différents, voici le code :
NSString *sentenceActivity = [object objectForKey:@sentence];
NSString *commentActivity = [object objectForKey:@comment];
NSString *username = [userfriend objectForKey:@username];
UILabel *colorLabel = (UILabel*) [cell viewWithTag:101];
[colorLabel setText:[NSString stringWithFormat:@%@ %@ : '%@'", username,sentenceActivity,commentActivity]];
Pour des raisons de lisibilité je souhaiterais que chaque NSString soit affiché dans une couleur, voire une police différente. Par exemple
username en rouge
sentenceActivity en noir
commentActivity en noir gras
En faisant des recherches j'ai pu comprendre qu'un NSString ne pouvait pas changer de couleur, il faudrait a priori passer par un "NSAttributedString"
J'ai utilisé l'exemple ci-dessous, qui fonctionne : le username s'affiche bien en rouge.
Ma question : Est-il possible d'associer cet NSAttributedString avec mes 3 NSString pour que mon label puisse être composé des trois couleurs différentes ?
UIColor *color = [UIColor redColor]; // select needed color
NSDictionary *attrs = @{ NSForegroundColorAttributeName : color };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:username attributes:attrs];
colorLabel.attributedText = attrStr;
si vous avez une petite idée merci par avance pour votre aide
Réponses
Utilises la version mutable : NSMutableAttributedString pour ça. Tu peux faire des append et autre.
Pour simplifier/résumer la différence entre NSString & NSAttributedString :
Le NSString ne peut pas changer la couleur, car le NSString n'est pour simplifier qu'une suite de caractères, la couleur, c'est au UILabel de la gérer, le NSString se fout complètement de l'UI.
Le NSAttributedString lui rajoute des propriétés de couleurs et autres au NSString, afin de dire quand il sera affiché, qu'il préférerait que ses propriétés additionnelles soient interprétées par le Label.
OK Larme merci beaucoup
Je trouve peu d'exemples pouvant m'aider à construire mon code il me faudrait un truc dans cette logique je suppose :
suis-je sur la bonne voie ?
Exemple :
Je n'ai pas mis les espaces et autres caractères comme les deux points, mais tu peux avoir ton idée là -dessus pour les rajouter, ne sachant pas ce que tu veux comme attributes (police/taille/couleur, etc).
Maintenant, comme c'est parfois un peu long à faire, tu peux passer par des convertisseurs, en embarquant ça dans du HTML, ou autre. Il y a des libs sur le net pour faciliter le tout.
Merci beaucoup pour l'exemple !
Du coup comment l'associer au "string" initial ci-dessous ?
J'ai tenté ceci en vain ça ne fonctionne pas :
Il n'y a pas de attributedStringWithFormat équivalent dans NSAttributedString.
Il faut que tu fasses toi-même le format.
gloups ... aurais-tu un petit exemple de format pour que je puisse en suivre la construction et l'adapter à mon projet ?
sera mieux !
Je ne vois pas a priori d'autre erreur potentielle dans ton code.
Oui Larme m'a bien aidé là dessus, maintenant ma difficulté est de l'inclure dans mon UILabel
Un truc comme çà peut-être...
Bien sûr les "selectedRange" sont définis en dur, mais il faut éviter çà ... A toi d'adapter à ton cas...
Merci, oui le problème avec les "range" c'est que dans mon cas il n'y a pas de longueur identique , c'est là où à présent je rame ...
me semble nickel.
Si tu mets un point d'arrêt, tu peux inspecter ton attributedString pour voir s'il a les bonnes couleurs, déjà .
Quel est le problème ?
Qu'est-ce qui ne marche pas ?
à‰ventuellement, dans IB, tu peux dire si le label accepte ou non des attributedString mais normalement si tu passes par le code ensuite, cette valeur de IB n'a pas d'importance.
PS qui n'a rien à voir mais pourra t'intéresser : tu peux transformer un ficher RTF en NSAttributedString
PPS : ne t'embête pas avec les range. Append est suffisant.
Désolée, j'ai mis un exemple avec des tailles de police différentes mais tu peux t'en inspirer pour les couleurs. Concernant la définition des ranges, il te suffit de les définir avec la longueur de tes différentes strings
en utilisant :
comme longueur des ranges...
Manière bateau :
On construit petit à petit la chaà®ne.
Manière un peu différente avec des placeholders manuels :
Problème : Si userName, commentActivity ou sentenceActivity contiennent <PlaceHolder1>, <PlaceHolder2> ou <PlaceHolder3>...
En bref, le soucis de "rangeOfString:", c'est qu'il retourne la première occurence trouvée, et si y'en a plusieurs et que tu ne voulais pas la première...
Je t'invite à créer un nouveau projet avec un unique UIViewController et un UILabel et de jouer avec les NSAttributedString pour comprendre comment cela fonctionne.
Manière un peu différente avec des placeholders manuels :
merci beaucoup à tous pour l'entraide ! ... pour le moment ça coince :
voici le code sur mon projet :
Moi j'aurais écrit des fonctions génériques pour mettre en forme les NSAttributedString, et concaténer les chaà®nes à la fin. Et je l'aurais réalisé en Swift, ma religion interdisant l'Obj-C.
Mise en pratique :
EDIT :
J'ai tapé ce code pour te donner une idée de la manière comment faire. Si je l'avais écris pour moi, j'aurais utilisé certaines fonctionnalités du Swift non traduisible en Obj-C.
Copie d'écran du résultat :
Le même, avec plusieurs Fonts :
En image :
C'est bien dommage (surtout l'élection de D Trump).
Mais je pense que tu peux reprendre la même logique en Obj-C.
Help... please .... petite traduction en Obj-C ? ...
Autre possibilité, peut-être plus facile à gérer :
Note pour Jopaone : Joanna est anglaise. On l'aide à parfaire sa (considérable) maitrise du français en lui signalant de petites erreurs ici et là .
::)
Du coup, c'est quoi la bonne orthographe ?
"que autolayout" ou "qu'autolayout" ?
Enorme !! Tellement évident ...
Je dirais "qu'autolayout" mais je suis moi-même franglais ...
Si mes souvenirs sont bon, on ne doit pas utiliser "qu'" devant un nom. Reste à savoir si autolayout est une chose ou le nom d'une chose. Ce n'est pas clair.
Joanna n'avait pas tapé "qu'" ou "que" mais .. autre chose. Elle a corrigé son post depuis.
EDIT : après recherche on doit toujours mettre "qu'" devant une voyelle (A, E, I, O, U, et Y).
C'est donc "qu'autolayout"
ça veut dire qu'à un moment donné, il y a NSString qui est nil. sentenceActivity? commentActivity? userName ?
Mais je t'ai donné ce qu'il fallait faire grosso-modo, c'est à toi aussi de débugguer de ton côté.
C'est un conseil qui pourra t'aider plus tard :
Ne jamais prendre à 100% pour argent comptant un code que tu peux trouver sur Internet.
Si le code semble "correct", ne pas hésiter à y trouver ses limites, cas non-gérés (comme c'est le cas ici avec ton crash). Ce sont souvent des indications de code qui fonctionnent dans le meilleur des cas.
En remplaçant initWithString:username avec initWithString:[NSString stringWithFormat:@%@", userName] pour les 3 cas, tu l'éviteras, mais tu devrais voir (null) à la place.
Donc plutôt :
initWithString:username avec initWithString:userName?userName:@UserName inconnu
initWithString:commentActivity avec initWithString:commentActivity?commentActivity:@Pas de commentaire
initWithString:sentenceActivity avec initWithString:sentenceActivity?sentenceActivity:@Pas de phrase
Ce sont des idées, rien de plus.
Oui merci beaucoup c'est débuggué et ça fonctionne nickel !
Encore merci à tous et bravo pour cette aide très collective