带有两种不同颜色文本的 UILabel

Posted

技术标签:

【中文标题】带有两种不同颜色文本的 UILabel【英文标题】:UILabel with text of two different colors 【发布时间】:2011-09-24 00:20:29 【问题描述】:

我想在UILabel 中显示这样的字符串:

有 5 个结果。

其中数字 5 为红色,字符串的其余部分为黑色。

如何在代码中做到这一点?

【问题讨论】:

@EmptyStack 这肯定不是,因为 ios 4 支持 NSAttributedString。请参阅下面的答案。 【参考方案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;


【讨论】:

【参考方案2】:

就我而言,我使用的是 Xcode 10.1。 Interface Builder的Label text中有一个在纯文本和属性文本之间切换的选项

希望这对其他人有帮助..!

【讨论】:

看起来 XCode 11.0 破坏了属性文本编辑器。因此,我尝试使用 TextEdit 创建文本,然后将其粘贴到 Xcode 中,效果出奇的好。【参考方案3】:

SwiftRichString 完美运行!您可以使用+ 连接两个属性字符串

【讨论】:

【参考方案4】:

我的答案还可以选择为所有出现的文本着色,而不仅仅是一次出现:“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

【讨论】:

我该如何使用它? 更新了我的答案,祝你有美好的一天:) 太棒了!这应该更高!【参考方案5】:

我通过为NSMutableAttributedString 创建一个category 来做到这一点

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

我对属性做了更多的实验,下面是结果,这里是SOURCECODE

这是结果

【讨论】:

您需要使用该方法为 NSMutableAttributedString 创建一个新类别...无论如何我将此示例添加到 github,您可以抓取并检查它github.com/anoop4real/NSMutableAttributedString-Color 但是我需要在一个字符串中设置所有字母表的颜色,不区分大小写......就像整个字符串中所有红色的“e”一样 No visible @interface for 'NSMutableAttributedString' 声明选择器 'setColorForText:withColor:' 我在 Swift4.1 中出现错误“使用未解析的标识符“NSForegroundColorAttributeName”,但我将“NSForegroundColorAttributeName”替换为“NSAttributedStringKey.foregroundColor”并正确构建。 @kj13 感谢通知,我更新了答案并添加了更多样式【参考方案6】:

Swift 4 及更高版本: 受anoop4real's solution 的启发,这是一个字符串扩展,可用于生成具有 2 种不同颜色的文本。

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

【讨论】:

【参考方案7】:

斯威夫特 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)

结果

斯威夫特 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)
        
    

结果:

【讨论】:

【参考方案8】:

通过使用下面的代码,您可以根据单词设置多种颜色。

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];

【讨论】:

【参考方案9】:

我自己的解决方案创建了一个类似下一个的方法:

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

它只适用于同一文本中的一种不同颜色,但您可以轻松地将其调整为同一句子中的更多颜色。

【讨论】:

【参考方案10】:
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

    

【讨论】:

【参考方案11】:

有一个 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)

【讨论】:

嗨,如果我想添加两个不同的颜色字符串,我该怎么做?我尝试使用您的示例并添加另一个示例,但它仍然只为其中一个着色.. 试试这个: 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。你也有解决这个问题的办法吗?【参考方案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;

【讨论】:

很好的解决方案,尤其适用于本地化字符串。非常感谢!【参考方案13】:

Anups 迅速回答。可以从任何类中重用。

在快速文件中

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;

【讨论】:

【参考方案14】:

给你

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;

【讨论】:

【参考方案15】:

这样做的方法是像这样使用NSAttributedString

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

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

我创建了一个UILabel extension to do it。

【讨论】:

我可以在上面添加目标吗?谢谢 我刚刚将您的扩展添加到我的项目中!谢谢! UILabel 的好类别。非常感谢。这应该是公认的答案。【参考方案16】:

JTAttributedLabel (by mystcolor) 允许您在 iOS 6 下使用 UILabel 中的属性字符串支持,同时通过其 JTAutoLabel 在 iOS 5 下使用其 JTAttributedLabel 类。

【讨论】:

【参考方案17】:

iOS 6 起,UIKit 支持绘制属性字符串,因此无需扩展或替换。

来自UILabel

@property(nonatomic, copy) NSAttributedString *attributedText;

您只需要建立您的NSAttributedString。基本上有两种方式:

    附加具有相同属性的文本块 - 为每个部分创建一个 NSAttributedString 实例并将它们附加到一个 NSMutableAttributedString

    从纯字符串创建属性文本,然后为给定范围添加属性 - 找到您的数字(或其他)的范围并在其上应用不同的颜色属性。

【讨论】:

【参考方案18】:

NSAttributedString 是要走的路。下面的问题有一个很好的答案,告诉你怎么做How do you use NSAttributedString

【讨论】:

【参考方案19】:

对于显示不需要可编辑的简短格式化文本,Core Text 是要走的路。有几个使用 NSAttributedString 和 Core Text 进行渲染的标签开源项目。例如,请参阅 CoreTextAttributedLabel 或 OHAttributedLabel。

【讨论】:

【参考方案20】:

在这种情况下,拥有一个 UIWebView 或多个 UILabel 可能被认为是矫枉过正。

我的建议是使用TTTAttributedLabel,它是支持NSAttributedString 的UILabel 的直接替代品。这意味着您可以非常轻松地将不同的样式应用于字符串中的不同范围。

【讨论】:

以上是关于带有两种不同颜色文本的 UILabel的主要内容,如果未能解决你的问题,请参考以下文章

在 TTTAttributedLabel 中,两种不同的文本颜色不起作用

带有两种颜色的 SVG/CSS 笔划虚线 - 有可能吗?

带有自定义项的 QTreeView

在swift4中查找按钮的文本颜色

如何在 Java 中设置标签(彩色文本)的颜色?

从 Notepad++ 复制带有颜色的文本