UILabel con texto de dos colores diferentes

Quiero mostrar una cadena como esta en un UILabel :

Hay 5 resultados.

Donde el número 5 es de color rojo y el rest de la cadena es negra.

¿Cómo puedo hacer esto en el código?

La forma de hacerlo es usar NSAttributedString así:

 NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString: label.attributedText]; [text addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(10, 1)]; [label setAttributedText: text]; 

UILabel una extensión UILabel para hacerlo .

Lo he hecho creando una category para NSMutableAttributedString

 -(void)setColorForText:(NSString*) textToFind withColor:(UIColor*) color { NSRange range = [self.mutableString rangeOfString:textToFind options:NSCaseInsensitiveSearch]; if (range.location != NSNotFound) { [self addAttribute:NSForegroundColorAttributeName value:color range:range]; } } 

Úselo como

 - (void) setColoredLabel { NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"Here is a red blue and green text"]; [string setColorForText:@"red" withColor:[UIColor redColor]]; [string setColorForText:@"blue" withColor:[UIColor blueColor]]; [string setColorForText:@"green" withColor:[UIColor greenColor]]; mylabel.attributedText = string; } 

SWIFT 3

 extension NSMutableAttributedString{ func setColorForText(_ textToFind: String, with color: UIColor) { let range = self.mutableString.range(of: textToFind, options: .caseInsensitive) if range.location != NSNotFound { addAttribute(NSForegroundColorAttributeName, value: color, range: range) } } } 

USO

 func setColoredLabel() { let string = NSMutableAttributedString(string: "Here is a red blue and green text") string.setColorForText("red", with: #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)) string.setColorForText("blue", with: #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)) string.setColorForText("green", with: #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)) mylabel.attributedText = string } 

SWIFT 4 @ kj13 Gracias por notificar

 // If no text is send, then the style will be applied to full text func setColorForText(_ textToFind: String?, with color: UIColor) { let range:NSRange? if let text = textToFind{ range = self.mutableString.range(of: text, options: .caseInsensitive) }else{ range = NSMakeRange(0, self.length) } if range!.location != NSNotFound { addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range!) } } 

He hecho más experimentos con los atributos y a continuación están los resultados, aquí está el SOURCECODE

Aquí está el resultado

Estilos

Aqui tienes

 NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:lblTemp.text]; [string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)]; [string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)]; [string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(11,5)]; lblTemp.attributedText = string; 
 //NSString *myString = @"I have to replace text 'Dr Andrew Murphy, John Smith' "; NSString *myString = @"Not a member?signin"; //Create mutable string from original one NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:myString]; //Fing range of the string you want to change colour //If you need to change colour in more that one place just repeat it NSRange range = [myString rangeOfString:@"signin"]; [attString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:(63/255.0) green:(163/255.0) blue:(158/255.0) alpha:1.0] range:range]; //Add it to the label - notice its not text property but it's attributeText _label.attributedText = attString; 

Swift 4

 // An attributed string extension to achieve colors on text. extension NSMutableAttributedString { func setColor(color: UIColor, forText stringValue: String) { let range: NSRange = self.mutableString.range(of: stringValue, options: .caseInsensitive) self.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range) } } // Try it with label let label = UILabel() label.frame = CGRect(x: 70, y: 100, width: 260, height: 30) let stringValue = "There are 5 results." let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: stringValue) attributedString.setColor(color: UIColor.red, forText: "5") label.font = UIFont.systemFont(ofSize: 26) label.attributedText = attributedString self.view.addSubview(label) 

Resultado

enter image description here

Swift 3

 func setColoredLabel() { var string: NSMutableAttributedString = NSMutableAttributedString(string: "redgreenblue") string.setColor(color: UIColor.redColor(), forText: "red") string.setColor(color: UIColor.greenColor(), forText: "green") string.setColor(color: UIColor.blueColor(, forText: "blue") mylabel.attributedText = string } func setColor(color: UIColor, forText stringValue: String) { var range: NSRange = self.mutableString.rangeOfString(stringValue, options: NSCaseInsensitiveSearch) if range != nil { self.addAttribute(NSForegroundColorAttributeName, value: color, range: range) } } 

Resultado:

enter image description here

Desde iOS 6 , UIKit admite el dibujo de cadenas atribuidas, por lo que no se necesita extensión o reemplazo.

De UILabel :

 @property(nonatomic, copy) NSAttributedString *attributedText; 

Solo necesitas construir tu NSAttributedString . Básicamente hay dos formas:

  1. Agregue trozos de texto con los mismos atributos: para cada parte, cree una instancia NSAttributedString y NSMutableAttributedString a un NSMutableAttributedString

  2. Crea texto atribuido a partir de una cadena simple y luego agrega atributos para rangos determinados: encuentra el rango de tu número (o lo que sea) y aplica un atributo de color diferente sobre eso.

Anups responde a la ligera. Se puede reutilizar de cualquier clase.

En archivo rápido

 extension NSMutableAttributedString { func setColorForStr(textToFind: String, color: UIColor) { let range = self.mutableString.rangeOfString(textToFind, options:NSStringCompareOptions.CaseInsensitiveSearch); if range.location != NSNotFound { self.addAttribute(NSForegroundColorAttributeName, value: color, range: range); } } } 

En algún controlador de vista

 let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: self.labelShopInYourNetwork.text!); attributedString.setColorForStr("YOUR NETWORK", color: UIColor(red: 0.039, green: 0.020, blue: 0.490, alpha: 1.0)); self.labelShopInYourNetwork.attributedText = attributedString; 

Tener una UIWebView o más de una UILabel podría considerarse excesivo para esta situación.

Mi sugerencia sería usar TTTAttributedLabel, que es un reemplazo directo para UILabel que admite NSAttributedString . Esto significa que puede aplicar fácilmente diferentes estilos a diferentes rangos en una cadena.

Para mostrar texto corto y formateado que no necesita ser editable, Core Text es el camino a seguir. Existen varios proyectos de código abierto para tags que usan NSAttributedString y Core Text para la representación. Vea CoreTextAttributedLabel o OHAttributedLabel por ejemplo.

JTAttributedLabel (by mystcolor) le permite usar el soporte de cadena atribuido en UILabel en iOS 6 y al mismo tiempo su clase JTAttributedLabel en iOS 5 a través de su JTAutoLabel.

NSAttributedString es el camino a seguir. La siguiente pregunta tiene una gran respuesta que le muestra cómo hacerlo. ¿Cómo se usa NSAttributedString?

Hay una solución Swift 3.0

 extension UILabel{ func setSubTextColor(pSubString : String, pColor : UIColor){ let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: self.text!); let range = attributedString.mutableString.range(of: pSubString, options:NSString.CompareOptions.caseInsensitive) if range.location != NSNotFound { attributedString.addAttribute(NSForegroundColorAttributeName, value: pColor, range: range); } self.attributedText = attributedString } } 

Y hay un ejemplo de llamada:

 let colorString = " (string in red)" self.mLabel.text = "classic color" + colorString self.mLabel.setSubTextColor(pSubString: colorString, pColor: UIColor.red) 

Para los usuarios de Xamarin tengo un método estático de C # donde paso una serie de cadenas, una matriz de UIColours y una matriz de UIFonts (necesitarán coincidir en longitud). La cadena atribuida se devuelve.

ver:

 public static NSMutableAttributedString GetFormattedText(string[] texts, UIColor[] colors, UIFont[] fonts) { NSMutableAttributedString attrString = new NSMutableAttributedString(string.Join("", texts)); int position = 0; for (int i = 0; i < texts.Length; i++) { attrString.AddAttribute(new NSString("NSForegroundColorAttributeName"), colors[i], new NSRange(position, texts[i].Length)); var fontAttribute = new UIStringAttributes { Font = fonts[i] }; attrString.AddAttributes(fontAttribute, new NSRange(position, texts[i].Length)); position += texts[i].Length; } return attrString; } 

Swift 4 y superior: inspirada por la solución de anoop4real , aquí hay una extensión de cadena que se puede utilizar para generar texto con 2 colores diferentes.

 extension String { func attributedStringForPartiallyColoredText(_ textToFind: String, with color: UIColor) -> NSMutableAttributedString { let mutableAttributedstring = NSMutableAttributedString(string: self) let range = mutableAttributedstring.mutableString.range(of: textToFind, options: .caseInsensitive) if range.location != NSNotFound { mutableAttributedstring.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range) } return mutableAttributedstring } } 

El siguiente ejemplo cambia el color del asterisco al rojo al tiempo que conserva el color original de la etiqueta para el rest del texto.

 label.attributedText = "Enter username *".attributedStringForPartiallyColoredText("*", with: #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)) 
 extension UILabel{ func setSubTextColor(pSubString : String, pColor : UIColor){ let attributedString: NSMutableAttributedString = self.attributedText != nil ? NSMutableAttributedString(attributedString: self.attributedText!) : NSMutableAttributedString(string: self.text!); let range = attributedString.mutableString.range(of: pSubString, options:NSString.CompareOptions.caseInsensitive) if range.location != NSNotFound { attributedString.addAttribute(NSForegroundColorAttributeName, value: pColor, range: range); } self.attributedText = attributedString } } 

Mi propia solución fue creada un método como el siguiente:

 -(void)setColorForText:(NSString*) textToFind originalText:(NSString *)originalString withColor:(UIColor*)color andLabel:(UILabel *)label{ NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:originalString]; NSRange range = [originalString rangeOfString:textToFind]; [attString addAttribute:NSForegroundColorAttributeName value:color range:range]; label.attributedText = attString; if (range.location != NSNotFound) { [attString addAttribute:NSForegroundColorAttributeName value:color range:range]; } label.attributedText = attString; } 

Funcionó con un solo color diferente en el mismo texto, pero puede adaptarlo fácilmente a más colores en la misma oración.

Al usar el código a continuación, puede establecer varios colores según la palabra.

 NSMutableArray * array = [[NSMutableArray alloc] initWithObjects:@"1 ball",@"2 ball",@"3 ball",@"4 ball", nil]; NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] init]; for (NSString * str in array) { NSMutableAttributedString * textstr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ,",str] attributes:@{NSForegroundColorAttributeName :[self getRandomColor]}]; [attStr appendAttributedString:textstr]; } UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(10, 300, 300, 30)]; lab.attributedText = attStr; [self.view addSubview:lab]; -(UIColor *) getRandomColor { CGFloat redcolor = arc4random() % 255 / 255.0; CGFloat greencolor = arc4random() % 255 / 255.0; CGFloat bluencolor = arc4random() % 255 / 255.0; return [UIColor colorWithRed:redcolor green:greencolor blue:bluencolor alpha:1.0]; } 

Mi respuesta también tiene la opción de colorear toda la aparición de un texto, no solo una ocurrencia de la misma: “wa ba wa ba dubdub”, puede colorear todas las ocurrencias de wa no solo la primera aparición como la respuesta aceptada.

 extension NSMutableAttributedString{ func setColorForText(_ textToFind: String, with color: UIColor) { let range = self.mutableString.range(of: textToFind, options: .caseInsensitive) if range.location != NSNotFound { addAttribute(NSForegroundColorAttributeName, value: color, range: range) } } func setColorForAllOccuranceOfText(_ textToFind: String, with color: UIColor) { let inputLength = self.string.count let searchLength = textToFind.count var range = NSRange(location: 0, length: self.length) while (range.location != NSNotFound) { range = (self.string as NSString).range(of: textToFind, options: [], range: range) if (range.location != NSNotFound) { self.addAttribute(NSForegroundColorAttributeName, value: color, range: NSRange(location: range.location, length: searchLength)) range = NSRange(location: range.location + range.length, length: inputLength - (range.location + range.length)) } } } }