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

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

有五个结果。

其中数字5是红色的,其余的字符串是黑色的。

我怎样才能用代码做到这一点?

108450 次浏览

NSAttributedString is the way to go. The following question has a great answer that shows you how to do it 如何使用 NSAttributedString

对于这种情况,拥有一个 UIWebView 或多个 UILabel 可能被认为是过分的。

我的建议是使用 属性标签,它是支持 NSAttributedString的 UILabel 的替代品。这意味着您可以非常容易地将不同的样式应用于字符串中的不同范围。

对于显示不需要编辑的短的格式化文本,Core Text是一种方法。对于使用 NSAttributedString和 Core Text 进行呈现的标签,有几个开源项目。例如,请参见 CoreTextAttributedLabelOHAttributedLabel

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

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


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

我创建了一个 UILabel 延期完成

IOS6以来,UIKit 支持绘制属性化字符串,因此不需要扩展或替换。

来自 UILabel:

@property(nonatomic, copy) NSAttributedString *attributedText;

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

  1. Append chunks of text with the same attributes - for each part create one NSAttributedString instance and append them to one NSMutableAttributedString

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

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

Here you go

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;

I have done this by creating a category for 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)
}
}
}

USAGE

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 Thanks for notifying

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

I have did more experiments with attributes and below are the results, here is the SOURCECODE

Here is the result

Styles

Anups answer in swift. Can be reused from any class.

列队

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


}
}

And there is an example of call :

let colorString = " (string in red)"
self.mLabel.text = "classic color" + colorString
self.mLabel.setSubTextColor(pSubString: colorString, pColor: UIColor.red)
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


}
}

我自己的解决办法就是创造一个类似下一个的方法:

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

它只在同一篇文章中使用一种不同的颜色,但是你可以很容易地在同一个句子中使用更多的颜色。

对于 Xamarin用户,我有一个静态 C # 方法,其中我传入一个字符串数组、一个 UIColours 数组和 UIFont 数组(它们需要匹配长度)。然后将属性化字符串传递回来。

see:

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

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

结果

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

结果:

enter image description here

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

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

Swift 4 and above: Inspired by Anoop4real 的解决方案, here's a String extension that can be used to generate text with 2 different colors.

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

我的答案也有颜色选项,可以选择所有出现的文字不只一个出现它: “ 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

SwiftRichString works perfect! You can use + to concatenate two attributed string

在我的例子中,我使用 Xcode 10.1。在 Interface Builder 的 Label 文本中,可以选择在纯文本和归属文本之间切换

enter image description here

希望这可以帮助其他人... !