Misha Misha - 2 months ago 11
iOS Question

NSForegroundColorAttributeName not working for UILabel

I have a problem changing substring color using "NSForegroundColorAttributeName". I'm confused since other attributes for the same substring are being applied(underline).

Also tried to use deprecated attribute "UITextAttributeTextColor" and other suggested attribute "kCTForegroundColorAttributeName" and got the same effect.

I'm compiling for iOS 7.

enter image description here

NSString *freeText = [NSString stringWithFormat:@"(%@)", self.me.activity.text];

int lblMaxWidth = arrImgView.origin.x - WPRConstraints.BorderOffset;
int lblMaxHeight = self.activityView.size.height - WPRConstraints.BorderOffset * 2;

RevUILabel *addActivityLbl = [[RevUILabel alloc] initWithFontNameMultiLine:[WPRFonts LattoBold]
size:16
sizeConstrain:CGSizeMake(lblMaxWidth,lblMaxHeight)];

addActivityLbl.text = [NSString stringWithFormat:@"%@ %@", Translate(self.me.activity.activityKey), freeText] ;
addActivityLbl.textColor = BlackColor;

NSMutableAttributedString *str = [addActivityLbl.attributedText mutableCopy];



[str addAttribute:NSUnderlineColorAttributeName value:[UIColor redColor] range:[addActivityLbl.text rangeOfString:freeText]];
[str addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:1] range:[addActivityLbl.text rangeOfString:freeText]];

[str addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:[addActivityLbl.text rangeOfString:freeText]];


addActivityLbl.attributedText = str;


addActivityLbl.frame = CGRectMake(WPRConstraints.BorderOffset,
WPRConstraints.BorderOffset,
addActivityLbl.size.width,
addActivityLbl.size.height);
[self.activityView addSubview:addActivityLbl];

Answer

The problem is this line:
NSMutableAttributedString *str = [addActivityLbl.attributedText mutableCopy];

I don't know the previous lines of your code, but it might be the case that addActivityLbl.attributedText is empty.

Secondly, using NSAttributedString with UILabel is not as reliable as using it with UITextView. The attributedText of a UILabel does inherit the attributes from the text of UILabel if the attributes are not explicitly provided.

Your addActivityLbl.textColor is black. And you still have not set your addActivityLbl.attributedText ForegroundColorAttribute. This means that your addActivityLbl.attributedText will inherit the BlackColor from your addActivityLbl.textColor.

This line will not work as expected; because you still have not set your addActivityLbl.attributedText. freeText has no range yet.

[str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:[addActivityLbl.text rangeOfString:freeText]];

The underlyning works because underlyning is not a property of addActivityLbl.text (not inherited by attributedText).

I recommend you to use UITextView instead (which is safer). An other option is to set your label.attributedText, before referencing to some range of it.