ios - ¿Es posible cambiar el color de una sola palabra en UITextView y UITextField?
objective-c nsattributedstring (9)
Después de establecer un texto atribuido, puede establecer typingAttributes of UITextView
con los valores que desea para su campo de entrada.
NSDictionary *attribs = @{
NSForegroundColorAttributeName:[UIColor colorWithHex:kUsernameColor],
NSFontAttributeName:[UIFont robotoRegularWithSize:40]
};
self.textView.typingAttributes = attribs;
¿Es posible cambiar el color de una sola palabra en UITextView y UITextField?
Si he escrito una palabra con un símbolo enfrente (por ejemplo: @word), ¿se puede cambiar el color?
La solución es esta:
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];
Para exponer sobre la respuesta de Jamal Kharrat, y para volver a escribirla en SWIFT, aquí está cómo hacerlo en una UITextView:
- Establezca su UITextView en "Atribuido" en el guión gráfico
- Haga clic con el botón derecho y arrastre al ícono ViewController en la parte superior de la vista (XC 6) y configure el delegado
- Crea un IBOutlet para tu UITextView (lo llamaremos "textView")
- Haga que su clase se ajuste a UITextViewDelegate
Aquí está la función de Jamal escrita 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
}
Ahora, necesitarás llamar a esta función. Para hacer esto cada vez que el usuario escribe un personaje, puede usar:
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
self.colorHastag()
return true
}
Notarás que cambié el color a azul. Puedes configurarlo en cualquier color. Además, puede quitar el: Tipo para cada variable. También querrá establecer becomeFirstResponder () y también manejar resignFirstResponder () para una buena experiencia de usuario. También podría arrojar algo de manejo de errores. Esto solo convertirá hashtags en azul. Tendrá que modificar o agregar un regEx para manejar el @.
Sí, es posible. Sin embargo, he descubierto que puede ser un dolor de cabeza tratar de usar NSMutableAttributesString
con un Range
Swift. El siguiente código le ayudará a tener que usar la clase Range
y devolverle una cadena atribuida con las palabras resaltadas con un color diferente.
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
}
}
Uso:
// 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
Se modificó la respuesta de @ fareed para swift 2.0 y esto está funcionando (probado en un patio de recreo):
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!")
esta es una implementación rápida de la respuesta de @Anoop Vaidya , esta función detecta cualquier palabra entre {| myword |}, colorea estas palabras en rojo y elimina los caracteres especiales, espero que esto pueda ayudar a otra persona:
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
}
puedes usarlo así:
self.msgText.attributedText = self.getColoredText("i {|love|} this!")
@fareed namrouti implementation reescrito en 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
}
Sí, necesita usar NSAttributedString
para eso, encuentre el RunningAppHere .
Escanee la palabra y encuentre el rango de su palabra y cambie su color.
EDITAR:
- (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: vea la captura de pantalla
-(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];
}