UILabel z tekstem w dwóch różnych kolorach

109

Chcę wyświetlić ciąg taki jak ten w UILabel:

Jest 5 wyników.

Gdzie cyfra 5 jest koloru czerwonego, a reszta sznurka jest czarna.

Jak mogę to zrobić w kodzie?

Piotr
źródło
6
@EmptyStack Z pewnością tak nie jest, ponieważ iOS 4 obsługuje NSAttributedString. Zobacz moją odpowiedź poniżej.
Mic Pringle

Odpowiedzi:

223

Aby to zrobić, użyj NSAttributedString:

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

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

Stworzyłem UILabel rozszerzenie, aby to zrobić .

João Costa
źródło
Czy mogę dodać do niego cele. Thnaks
UserDev
Właśnie dodałem Twoje rozszerzenie do mojego projektu! Dzięki!
Zeb
Dobra kategoria dla UILabel. Wielkie dzięki. To powinna być akceptowana odpowiedź.
Pradeep Reddy Kypa
63

Zrobiłem to, tworząc 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];
    }
}

Użyj tego jak

- (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)
        }
    }
}

STOSOWANIE

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 Dziękujemy za powiadomienie

// 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!)
    }
}

Przeprowadziłem więcej eksperymentów z atrybutami, a poniżej są wyniki, oto KOD ŹRÓDŁOWY

Oto wynik

Style

anoop4real
źródło
2
Musisz utworzyć nową kategorię dla NSMutableAttributedString za pomocą metody ... w każdym razie dodałem ten przykład do github, możesz go pobrać i sprawdzić github.com/anoop4real/NSMutableAttributedString-Color
anoop4real
Ale muszę ustawić kolor całego alfabetu z inasesensitive w ciągu .... jak wszystkie "e" w kolorze czerwonym całego ciągu
Ravi Ojha
Brak widocznego @interface dla „NSMutableAttributedString” deklaruje selektor „setColorForText: withColor:”
ekashking
1
Wystąpił błąd „Użycie nierozwiązanego identyfikatora„ NSForegroundColorAttributeName ”ze Swift4.1, ale zamieniam„ NSForegroundColorAttributeName ”na„ NSAttributedStringKey.foregroundColor ”i buduję poprawnie.
kj13
1
@ kj13 Dzięki za powiadomienie, zaktualizowałem odpowiedź i dodałem kilka innych stylów
anoop4real
25

Proszę bardzo

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;
Hardik Mamtora
źródło
20

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

Wynik

wprowadź opis obrazu tutaj


Szybki 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)
        }
    }

Wynik:

wprowadź opis obrazu tutaj

Krunal
źródło
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;
raju dontiboina
źródło
6

Od iOS 6 UIKit obsługuje rysowanie przypisanych ciągów, więc nie jest potrzebne żadne rozszerzenie ani wymiana.

Od UILabel:

@property(nonatomic, copy) NSAttributedString *attributedText;

Musisz tylko rozbudować swoją NSAttributedString. Zasadniczo istnieją dwa sposoby:

  1. Dołącz fragmenty tekstu o tych samych atrybutach - dla każdej części utwórz jedno NSAttributedStringwystąpienie i dołącz je do jednegoNSMutableAttributedString

  2. Utwórz przypisany tekst ze zwykłego ciągu, a następnie dodaj przypisany dla podanych zakresów - znajdź zakres swojego numeru (lub cokolwiek) i zastosuj do niego inny atrybut koloru.

Tricertops
źródło
6

Anups odpowiada szybko. Może być ponownie użyty z dowolnej klasy.

W szybkim pliku

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);
        }

    }
}

W niektórych widok kontrolera

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;
Deepak Thakur
źródło
4

Posiadanie UIWebView lub więcej niż jednego UILabel można uznać za przesadę w tej sytuacji.

Moją sugestią byłoby użycie TTTAttributedLabel, który jest zastępczym zamiennikiem dla UILabel, który obsługuje NSAttributedString . Oznacza to, że możesz bardzo łatwo zastosować różne style do różnych zakresów w ciągu.

Mic Pringle
źródło
3

NSAttributedStringjest droga do zrobienia. Poniższe pytanie ma świetną odpowiedź, która pokazuje, jak to zrobić. Jak używać NSAttributedString

werner
źródło
3

JTAttributedLabel (od mystcolor) umożliwia użycie przypisanej obsługi ciągów w UILabel w systemie iOS 6 i jednocześnie jego klasy JTAttributedLabel w iOS 5 za pośrednictwem JTAutoLabel.

Johan Kool
źródło
2

Istnieje rozwiązanie 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

    }
}

Oto przykład połączenia:

let colorString = " (string in red)"
self.mLabel.text = "classic color" + colorString
self.mLabel.setSubTextColor(pSubString: colorString, pColor: UIColor.red)
Kevin ABRIOUX
źródło
Cześć, jak mam to zrobić, jeśli chcę dodać dwa różne ciągi kolorów? Próbowałem użyć twojego przykładu i po prostu
dodałem
Spróbuj tego: let colorString = "(ciąg na czerwono)" let colorStringGreen = "(ciąg na zielono)" self.mLabel.text = "klasyczny kolor" + colorString + colorStringGreen self.mLabel.setSubTextColor (pSubString: colorString, pColor: UIColor .red) self.mLabel.setSubTextColor (pSubString: colorStringGreen, pColor: UIColor.green)
Kevin ABRIOUX
To dziwne, ale nadal nie zmienia obu: s24.postimg.org/ds0rpyyut/… .
Erik Auranaune
Problem polega na tym, że jeśli dwa ciągi są takie same, koloruje tylko jeden z nich, spójrz tutaj: pastebin.com/FJZJTpp3 . Masz też na to rozwiązanie?
Erik Auranaune
2

Swift 4 i nowszy: Zainspirowany rozwiązaniem anoop4real , oto rozszerzenie String, którego można użyć do wygenerowania tekstu w 2 różnych kolorach.

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
    }
}

Poniższy przykład zmienia kolor gwiazdki na czerwony, zachowując oryginalny kolor etykiety dla pozostałego tekstu.

label.attributedText = "Enter username *".attributedStringForPartiallyColoredText("*", with: #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1))
Politycznie niezależny
źródło
2

Moja odpowiedź ma również możliwość pokolorowania całego wystąpienia tekstu, a nie tylko jednego jego wystąpienia: „wa ba wa ba dubdub”, można pokolorować całe wystąpienie wa nie tylko pierwszego wystąpienia, jak przyjęta odpowiedź.

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

Teraz możesz to zrobić:

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
Kompilator Alsh
źródło
Jak mogę tego używać?
pableiros
1
Zaktualizowałem moją odpowiedź,
życzę
1

Dla użytkowników platformy Xamarin mam statyczny C # metodę , w której przekazuję tablicę ciągów, tablicę kolorów UIColours i tablicę UIFonts (będą musiały pasować pod względem długości). Przypisany ciąg jest następnie przekazywany z powrotem.

widzieć:

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;

    }
Craig Champion
źródło
1

W moim przypadku używam Xcode 10.1. Istnieje możliwość przełączania między zwykłym tekstem a tekstem z atrybutami w tekście etykiety w programie Interface Builder

wprowadź opis obrazu tutaj

Mam nadzieję, że to może pomóc komuś innemu ..!

BharathRao
źródło
2
Wygląda na to, że XCode 11.0 zepsuł edytor Attributed Text. Próbowałem więc użyć TextEdit, aby utworzyć tekst, a następnie wkleiłem go do Xcode i zadziałało zaskakująco dobrze.
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

    }
}
Dipak Panchasara
źródło
0

Moje własne rozwiązanie zostało stworzone metodą taką jak następna:

-(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; }

Działał tylko z jednym innym kolorem w tym samym tekście, ale można go łatwo dostosować do większej liczby kolorów w tym samym zdaniu.

shontauro
źródło
0

Korzystając z poniższego kodu, możesz ustawić wiele kolorów na podstawie słowa.

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];
}
Hari C.
źródło
0

SwiftRichStringdziała idealnie! Możesz użyć +do połączenia dwóch przypisanych ciągów

fujianjin6471
źródło