UILabel con texto de dos colores diferentes


109

Quiero mostrar una cadena como esta en un UILabel:

Hay 5 resultados.

Donde el número 5 es de color rojo y el resto de la cuerda es negro.

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


6
@EmptyStack Este ciertamente no es el caso ya que iOS 4 es compatible con NSAttributedString. Vea mi respuesta a continuación.
Mic Pringle

Respuestas:


223

La forma de hacerlo es usar NSAttributedStringasí:

NSMutableAttributedString *text = 
 [[NSMutableAttributedString alloc] 
   initWithAttributedString: label.attributedText];

[text addAttribute:NSForegroundColorAttributeName 
             value:[UIColor redColor] 
             range:NSMakeRange(10, 1)];
[label setAttributedText: text];

Creé una UILabel extensión para hacerlo .


¿Puedo agregar objetivos en él? Thnaks
UserDev

¡Acabo de agregar su extensión a mi proyecto! ¡Gracias!
Zeb

Buena categoría para UILabel. Muchas gracias. Esta debería ser la respuesta aceptada.
Pradeep Reddy Kypa

63

He hecho esto creando un categoryforNSMutableAttributedString

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

// 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 atributos y a continuación están los resultados, aquí está el SOURCECODE

Aqui esta el resultado

Estilos


2
Necesita crear una nueva categoría para NSMutableAttributedString con el método ... de todos modos agregué esta muestra a github, puede tomarla
anoop4real

Pero necesito establecer el color de todo el alfabeto con incasesensitive en una cadena ... como toda "e" en color rojo de toda la cadena
Ravi Ojha

Sin @interface visible para 'NSMutableAttributedString' declara el selector 'setColorForText: withColor:'
ekashking

1
Recibí el error 'Uso del identificador no resuelto' NSForegroundColorAttributeName 'con Swift4.1, pero reemplazo' NSForegroundColorAttributeName 'por' NSAttributedStringKey.foregroundColor 'y construyo correctamente.
kj13

1
@ kj13 Gracias por notificarme, actualicé la respuesta y agregué algunos estilos más
anoop4real

25

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;

20

Rápido 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

ingrese la descripción de la imagen aquí


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:

ingrese la descripción de la imagen aquí


12
//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;

6

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

De UILabel:

@property(nonatomic, copy) NSAttributedString *attributedText;

Solo necesita construir su NSAttributedString. Básicamente, hay dos formas:

  1. Agregue fragmentos de texto con los mismos atributos: para cada parte, cree una NSAttributedStringinstancia y añádalas a unaNSMutableAttributedString

  2. Cree texto con atributos a partir de una cadena simple y luego agregue atributos para rangos dados: busque el rango de su número (o lo que sea) y aplique un atributo de color diferente en eso.


6

Anups responde rápidamente. 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;

4

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

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




3

JTAttributedLabel (por mystcolor) le permite usar el soporte de cadenas atribuidas en UILabel bajo iOS 6 y al mismo tiempo su clase JTAttributedLabel bajo iOS 5 a través de su JTAutoLabel.


2

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

Hola, ¿cómo hago esto si quiero agregar dos cadenas de colores diferentes? Intenté usar su ejemplo y agregar otro, pero todavía solo colorea uno de ellos ..
Erik Auranaune

Pruebe esto: let colorString = "(cadena en rojo)" let colorStringGreen = "(cadena en verde)" self.mLabel.text = "color clásico" + colorString + colorStringGreen self.mLabel.setSubTextColor (pSubString: colorString, pColor: UIColor .red) self.mLabel.setSubTextColor (pSubString: colorStringGreen, pColor: UIColor.green)
Kevin ABRIOUX

Esto es extraño, todavía no cambia ambos: s24.postimg.org/ds0rpyyut/… .
Erik Auranaune

Un problema es que si las dos cadenas son iguales, solo colorea una de ellas, mira aquí: pastebin.com/FJZJTpp3 . ¿También tienes una solución para esto?
Erik Auranaune

2

Swift 4 y superior: inspirada en la solución de anoop4real , aquí hay una extensión de cadena que se puede usar 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 a rojo y conserva el color de la etiqueta original para el texto restante.

label.attributedText = "Enter username *".attributedStringForPartiallyColoredText("*", with: #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1))

2

Mi respuesta también tiene la opción de colorear todas las ocurrencias de un texto, no solo una ocurrencia del mismo: "wa ba wa ba dubdub", puede colorear todas las ocurrencias de wa no solo la primera ocurrencia 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))
            }
        }
    }
}

Ahora puedes hacer esto:

let message = NSMutableAttributedString(string: "wa ba wa ba dubdub")
message.setColorForText(subtitle, with: UIColor.red) 
// or the below one if you want all the occurrence to be colored 
message.setColorForAllOccuranceOfText("wa", with: UIColor.red) 
// then you set this attributed string to your label :
lblMessage.attributedText = message

¿Y cómo puedo usarlo?
pableiros

1
Actualicé mi respuesta, que tenga un buen día :)
Compilador de Alsh

1

Para los usuarios de Xamarin , tengo un método C # estático en el que paso una matriz de cadenas, una matriz de UIColours y una matriz de UIFonts (deberán coincidir en longitud). Luego, 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;

    }

1

En mi caso, estoy usando Xcode 10.1. Existe la opción de cambiar entre texto sin formato y texto atribuido en el texto de la etiqueta en Interface Builder

ingrese la descripción de la imagen aquí

Espero que esto pueda ayudar a alguien más ...!


2
Parece que XCode 11.0 rompió el editor de texto atribuido. Entonces, intenté usar TextEdit para crear el texto, luego lo pegué en Xcode y funcionó sorprendentemente bien.
Brainware

0
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

    }
}

0

Mi propia solución fue creada con 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 puedes adaptarlo fácilmente a más colores en la misma oración.


0

Al usar el siguiente código, 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];
}

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.