UILabel с текстом двух разных цветов

109

Я хочу отобразить такую ​​строку в UILabel:

Есть 5 результатов.

Где цифра 5 красного цвета, а остальная часть строки черная.

Как я могу сделать это в коде?

Питер
источник
6
@EmptyStack Это определенно не так, поскольку iOS 4 поддерживает NSAttributedString. Смотрите мой ответ ниже.
Mic Pringle

Ответы:

223

Это можно сделать NSAttributedStringследующим образом:

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

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

Я создал UILabel расширение для этого .

Жоао Коста
источник
Могу я добавить на него цели. Thnaks
UserDev 08
Я только что добавил ваше расширение в свой проект! Спасибо!
Зеб
Хорошая категория для UILabel. Большое спасибо. Это должен быть принятый ответ.
Прадип Редди Кипа
63

Я сделал это, создав categoryдля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];
    }
}

Используйте это как

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

ИСПОЛЬЗОВАНИЕ

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 Спасибо за уведомление.

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

Я провел больше экспериментов с атрибутами, и ниже представлены результаты, вот ИСТОЧНИК

Вот результат

Стили

anoop4real
источник
2
Вам нужно создать новую категорию для NSMutableAttributedString с помощью метода ... в любом случае я добавил этот образец в github, вы можете взять и проверить его github.com/anoop4real/NSMutableAttributedString-Color
anoop4real
Но мне нужно установить цвет всего алфавита с помощью нечувствительности в строке .... как все «е» в красном цвете всей строки
Рави Оджха
Нет видимого @interface для 'NSMutableAttributedString' объявляет селектор 'setColorForText: withColor:'
ekashking 01
1
Я получил ошибку «Использование неразрешенного идентификатора NSForegroundColorAttributeName» в Swift4.1, но я заменяю NSForegroundColorAttributeName на «NSAttributedStringKey.foregroundColor» и строю правильно.
kj13
1
@ kj13 Спасибо за уведомление, я обновил ответ и добавил еще несколько стилей
anoop4real
25

Ну вот

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

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)

Результат

введите описание изображения здесь


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

Результат:

введите описание изображения здесь

Krunal
источник
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

Начиная с iOS 6 , UIKit поддерживает рисование строк с атрибутами, поэтому расширение или замена не требуется.

Откуда UILabel:

@property(nonatomic, copy) NSAttributedString *attributedText;

Вам просто нужно нарастить свой NSAttributedString. В основном есть два способа:

  1. Добавляйте фрагменты текста с одинаковыми атрибутами - для каждой части создайте один NSAttributedStringэкземпляр и добавьте их в одинNSMutableAttributedString

  2. Создайте текст с атрибутами из простой строки, а затем добавьте атрибуты для заданных диапазонов - найдите диапазон своего номера (или чего-то еще) и примените к нему другой атрибут цвета.

Трисертопс
источник
6

Анупс отвечает быстро. Можно повторно использовать из любого класса.

В быстром файле

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

    }
}

В некотором контроллере представления

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

Наличие UIWebView или нескольких UILabel в этой ситуации может считаться излишним.

Я предлагаю использовать TTTAttributedLabel, который является заменой для UILabel, который поддерживает NSAttributedString . Это означает, что вы можете очень легко применять разные стили к разным диапазонам в строке.

Мик Прингл
источник
4

Для отображения короткого отформатированного текста, который не нужно редактировать, лучше всего подойдет Core Text . Существует несколько проектов с открытым исходным кодом для этикеток, которые используют NSAttributedStringи Core Text для рендеринга. См., Например, CoreTextAttributedLabel или OHAttributedLabel .

омз
источник
3

JTAttributedLabel (by mystcolor) позволяет использовать поддержку строк с атрибутами в UILabel под iOS 6 и в то же время его класс JTAttributedLabel под iOS 5 через его JTAutoLabel.

Йохан Кул
источник
2

Есть решение 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

    }
}

И вот пример звонка:

let colorString = " (string in red)"
self.mLabel.text = "classic color" + colorString
self.mLabel.setSubTextColor(pSubString: colorString, pColor: UIColor.red)
Кевин АБРИОУКС
источник
Привет, как мне это сделать, если я хочу добавить два разных colorString? Я попытался использовать ваш пример и просто добавить еще один, но он все еще окрашивает только один из них ..
Эрик Ауранауне
Попробуйте следующее: let colorString = "(строка красного цвета)" let colorStringGreen = "(строка зеленого цвета)" self.mLabel.text = "classic color" + colorString + colorStringGreen self.mLabel.setSubTextColor (pSubString: colorString, pColor: UIColor .red) self.mLabel.setSubTextColor (pSubString: colorStringGreen, pColor: UIColor.green)
Кевин АБРИОУКС
Это странно, это все равно не меняет обоих: s24.postimg.org/ds0rpyyut/… .
Эрик Ауранауне
Проблема в том, что если две строки одинаковы, он окрашивает только одну из них, посмотрите здесь: pastebin.com/FJZJTpp3 . У вас есть исправление для этого?
Эрик Ауранауне
2

Swift 4 и выше: Вдохновленный решением anoop4real , вот расширение String, которое можно использовать для создания текста с двумя разными цветами.

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

В следующем примере цвет звездочки изменяется на красный, но для оставшегося текста сохраняется исходный цвет метки.

label.attributedText = "Enter username *".attributedStringForPartiallyColoredText("*", with: #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1))
Maverick
источник
2

В моем ответе также есть возможность раскрасить все вхождения текста, а не только одно его вхождение: «wa ba wa ba dubdub», вы можете раскрасить все вхождения wa, а не только первое вхождение, как принятый ответ.

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

Теперь вы можете это сделать:

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
Компилятор alsh
источник
И как я могу его использовать?
pableiros
1
Обновил мой ответ, хорошего дня :)
компилятор
1

Для пользователей Xamarin у меня есть статический метод C #, в котором я передаю массив строк, массив UIColours и массив UIFonts (они должны совпадать по длине). Приписанная строка затем передается обратно.

видеть:

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

В моем случае я использую Xcode 10.1. Существует возможность переключения между обычным текстом и текстом с атрибутами в тексте метки в Interface Builder.

введите описание изображения здесь

Надеюсь, это поможет кому-то другому ..!

Бхаратрао
источник
2
Похоже, что XCode 11.0 сломал редактор текста с атрибутами. Итак, я попытался использовать TextEdit для создания текста, а затем вставил его в Xcode, и это сработало на удивление хорошо.
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

Мое собственное решение было создано методом, подобным следующему:

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

Он работал только с одним другим цветом в одном и том же тексте, но вы можете легко адаптировать его к большему количеству цветов в одном предложении.

Shontauro
источник
0

Используя приведенный ниже код, вы можете установить несколько цветов на основе слова.

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];
}
Хари с
источник
0

SwiftRichStringработает отлично! Вы можете использовать +для объединения двух строк с атрибутами

fujianjin6471
источник