Est-il possible de changer la couleur d'un seul mot dans UITextView et UITextField?
Si j'ai tapé un mot avec un symbole devant (par exemple: @Word), sa couleur peut-elle être changée?
Oui, vous devez utiliser NSAttributedString
pour cela, recherchez le RunningAppHere .
Parcourez le mot, repérez la plage de votre mot et changez sa couleur.
MODIFIER:
- (IBAction)colorWord:(id)sender {
NSMutableAttributedString * string = [[NSMutableAttributedString alloc]initWithString:self.text.text];
NSArray *words=[self.text.text componentsSeparatedByString:@" "];
for (NSString *Word in words) {
if ([Word hasPrefix:@"@"]) {
NSRange range=[self.text.text rangeOfString:Word];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
}
}
[self.text setAttributedText:string];
}
EDIT 2: voir la capture d'écran
La réponse modifiée de @ fareed pour Swift 2.0 et cela fonctionne (testé dans un terrain de jeu):
func getColoredText(text: String) -> NSMutableAttributedString {
let string:NSMutableAttributedString = NSMutableAttributedString(string: text)
let words:[String] = text.componentsSeparatedByString(" ")
var w = ""
for Word in words {
if (Word.hasPrefix("{|") && Word.hasSuffix("|}")) {
let range:NSRange = (string.string as NSString).rangeOfString(Word)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
w = Word.stringByReplacingOccurrencesOfString("{|", withString: "")
w = w.stringByReplacingOccurrencesOfString("|}", withString: "")
string.replaceCharactersInRange(range, withString: w)
}
}
return string
}
getColoredText("i {|love|} this!")
ceci est une implémentation Swift de @Anoop Vaidya answer, cette fonction détecte tout mot compris entre {| myword |}, colorie ces mots en rouge et supprime les caractères spéciaux. J'espère que cela pourra aider quelqu'un d'autre:
func getColoredText(text:String) -> NSMutableAttributedString{
var string:NSMutableAttributedString = NSMutableAttributedString(string: text)
var words:[NSString] = text.componentsSeparatedByString(" ")
for (var Word:NSString) in words {
if (Word.hasPrefix("{|") && Word.hasSuffix("|}")) {
var range:NSRange = (string.string as NSString).rangeOfString(Word)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
Word = Word.stringByReplacingOccurrencesOfString("{|", withString: "")
Word = Word.stringByReplacingOccurrencesOfString("|}", withString: "")
string.replaceCharactersInRange(range, withString: Word)
}
}
return string
}
vous pouvez l'utiliser comme ceci:
self.msgText.attributedText = self.getColoredText("i {|love|} this!")
@fareed namrouti implémentation réécrite dans Swift 3
func getColoredText(text: String) -> NSMutableAttributedString {
let string:NSMutableAttributedString = NSMutableAttributedString(string: text)
let words:[String] = text.components(separatedBy:" ")
var w = ""
for Word in words {
if (Word.hasPrefix("{|") && Word.hasSuffix("|}")) {
let range:NSRange = (string.string as NSString).range(of: Word)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: range)
w = Word.replacingOccurrences(of: "{|", with: "")
w = w.replacingOccurrences(of:"|}", with: "")
string.replaceCharacters(in: range, with: w)
}
}
return string
}
-(void)colorHashtag
{
NSMutableAttributedString * string = [[NSMutableAttributedString alloc]initWithString:textView.text];
NSString *str = textView.text;
NSError *error = nil;
//I Use regex to detect the pattern I want to change color
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:textView.text options:0 range:NSMakeRange(0, textView.text.length)];
for (NSTextCheckingResult *match in matches) {
NSRange wordRange = [match rangeAtIndex:0];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:wordRange];
}
[textView setAttributedText:string];
}
Après avoir défini un texte attribué, vous pouvez définir typingAttributes of UITextView
avec les valeurs souhaitées pour le champ de saisie.
NSDictionary *attribs = @{
NSForegroundColorAttributeName:[UIColor colorWithHex:kUsernameColor],
NSFontAttributeName:[UIFont robotoRegularWithSize:40]
};
self.textView.typingAttributes = attribs;
Oui c'est possible. Cependant, j'ai constaté qu'il peut s'agir d'un mal de tête en essayant d'utiliser NSMutableAttributesString
avec un Swift Range
. Le code ci-dessous vous évitera de devoir utiliser la classe Range
et vous renverra une chaîne attribuée avec les mots mis en surbrillance d'une couleur différente.
extension String {
func getRanges(of string: String) -> [NSRange] {
var ranges:[NSRange] = []
if contains(string) {
let words = self.components(separatedBy: " ")
var position:Int = 0
for Word in words {
if Word.lowercased() == string.lowercased() {
let startIndex = position
let endIndex = Word.characters.count
let range = NSMakeRange(startIndex, endIndex)
ranges.append(range)
}
position += (Word.characters.count + 1) // +1 for space
}
}
return ranges
}
func highlight(_ words: [String], this color: UIColor) -> NSMutableAttributedString {
let attributedString = NSMutableAttributedString(string: self)
for Word in words {
let ranges = getRanges(of: Word)
for range in ranges {
attributedString.addAttributes([NSForegroundColorAttributeName: color], range: range)
}
}
return attributedString
}
}
Usage:
// The strings you're interested in
let string = "The dog ran after the cat"
let words = ["the", "ran"]
// Highlight words and get back attributed string
let attributedString = string.highlight(words, this: .yellow)
// Set attributed string
textView.attributedText = attributedString
Pour expliquer la réponse de Jamal Kharrat et la réécrire dans Swift, voici comment procéder dans un UITextView:
Voici la fonction de Jamal écrite en Swift:
func colorHastag(){
var string:NSMutableAttributedString = NSMutableAttributedString(string: textView.text)
var str:NSString = textView.text
var error:NSError?
var match:NSTextCheckingResult?
var regEx:NSRegularExpression = NSRegularExpression(pattern: "#(\\w+)", options: nil, error: &error)!
var matches:NSArray = regEx.matchesInString(textView.text, options: nil, range: NSMakeRange(0, countElements(textView.text)))
for (match) in matches {
var wordRange:NSRange = match.rangeAtIndex(0)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.blueColor(), range: wordRange)
}
textView.attributedText = string
}
Maintenant, vous aurez besoin d'appeler cette fonction. Pour ce faire, chaque fois que l'utilisateur tape un caractère, vous pouvez utiliser:
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
self.colorHastag()
return true
}
Vous remarquerez que j'ai changé la couleur en bleu. Vous pouvez le définir sur n'importe quelle couleur. En outre, vous pouvez supprimer le: Type pour chaque variable. Vous voudrez également définir devenFirstResponder () et gérer également resignFirstResponder () pour une bonne expérience utilisateur. Vous pouvez également ajouter un peu de gestion des erreurs. Cela convertira uniquement les hashtags en bleu. Vous devrez modifier ou ajouter un regEx pour gérer le @.
La solution est la suivante:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
NSArray *words=[txtDescription.text componentsSeparatedByString:@" "];
for (NSString *Word in words)
{
if ([Word hasPrefix:@"@"] || [Word hasPrefix:@"#"])
{
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ", Word]
attributes:@{NSFontAttributeName: [UIFont fontWithName:FONT_LIGHT size:15],
NSForegroundColorAttributeName: [ImageToolbox colorWithHexString:@"f64d5a"]}]];
}
else // normal text
{
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ", Word]
attributes:@{NSFontAttributeName: [UIFont fontWithName:FONT_LIGHT size:15],
NSForegroundColorAttributeName: [ImageToolbox colorWithHexString:@"3C2023"]}]];
}
}
if([[attributedString string] hasSuffix:@" "]) // loose the last space
{
NSRange lastCharRange;
lastCharRange.location=0;
lastCharRange.length=[attributedString string].length-1;
attributedString=[[NSMutableAttributedString alloc] initWithAttributedString:[attributedString attributedSubstringFromRange:lastCharRange]];
}
[txtDescription setAttributedText:attributedString];