Incorrect display of the UILabel attribute

I have installed the UILabel using attributedText to get the font I want, and I change the UILabel attributedText property quite often. It seems like about 50% of the time it seems to make new text on top of the old text without removing the old one. My code now looks like this:

// Attributes initialization
self.labelAttributes = [NSMutableDictionary dictionary];
[self.labelAttributes setObject: [UIFont fontWithName:@"Helvetica Neue" size:21] forKey: NSFontAttributeName];
[self.labelAttributes setObject: [UIColor whiteColor] forKey: NSForegroundColorAttributeName];
[self.labelAttributes setObject: [NSNumber numberWithFloat: -3.0] forKey: NSStrokeWidthAttributeName];
[self.labelAttributes setObject: [UIColor blackColor] forKey: NSStrokeColorAttributeName];

// Clear UILabel attributedString
self.userLabel.attributedText = [[NSAttributedString alloc] initWithString:@"" attributes:self.labelAttributes];
// Also attempted this with nil;

// Set UILabel to string, where self.userName and self.userAge are just regular strings. 
NSString *labelString = [NSString stringWithFormat:@"%@, %@", self.userName, self.userAge];
self.userLabel.attributedText = [[NSAttributedString alloc] initWithString:labelString attributes:self.labelAttributes];


When it works, it looks like this:

enter image description here

When it doesn't work, it looks like this:

enter image description here

This appears to be the last username plus the current username superimposed on each other.

I can't find a good way to ensure that the shortcut is cleaned up, and I'm not sure how to debug it. (I've tried using visual debugging in XCode 6, but it still thinks it's just one shortcut, with the new user text being a text attribute.)


source to share

5 answers

Interesting. Not sure why it doesn't work. Your code seems fine. The only thing I can think of is if it is a label in a table view cell and it is reset after it is turned off and then on screen? Otherwise, I don’t know.

Here's another way to do the same, which works for me.

NSString *labelString = [NSString stringWithFormat:@"%@, %@", self.userName, self.userAge];
self.userLabel.text = labelString;
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithAttributedString:self.userLabel.attributedText];
[attStr addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica Neue" size:21] range:NSMakeRange(0, self.userLabel.length)];
[attStr addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, self.userLabel.length)];
[attStr addAttribute:NSStrokeWidthAttributeName value:[NSNumber numberWithFloat:-3.0f] range:NSMakeRange(0, self.userLabel.length)];
[attStr addAttribute:NSStrokeColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, self.userLabel.length)];
//or 1 liner
//[attStr addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"Helvetica Neue" size:21], NSFontAttributeName, [UIColor whiteColor], NSForegroundColorAttributeName, [NSNumber numberWithFloat:-3.0f], NSStrokeWidthAttributeName, [UIColor blackColor], NSStrokeColorAttributeName, nil] range:NSMakeRange(0, self.userLabel.length)];
[self.userLabel setAttributedText:attStr];


Also, I don't understand why you just can't set a shortcut to start these properties (unless they change across the entire label). You could just do:

NSString *labelString = [NSString stringWithFormat:@"%@, %@", self.userName, self.userAge];
self.userLabel.text = labelString;
self.userLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:21];
self.userLabel.textColor = [UIColor blackColor];
//Then set the stroke with one attribute


Hope this helps! Happy coding.



You can do it like this:

self.userLabel.attributedText = [[NSAttributedString alloc] 
initWithString:@"string to both stroke and fill" 
             NSStrokeWidthAttributeName: [NSNumber numberWithFloat:-3.0],
             NSStrokeColorAttributeName: [UIColor blackColor],
             NSForegroundColorAttributeName: [UIColor whiteColor]




I think I've seen this before, using UITableCell reuse and dynamic table cell heights defined at runtime. This happens when the cells are set to height 0, if I remember correctly.

If you are in the above scenario try to include clipsToBounds

to include in UITableViewCell or in top reusable view. Inclusion clipsToBounds

causes labels, etc. Does not infer from the view when the size or height of the view frame is set to zero.



It should be correct by default, but you can still try:

self.userLabel.clearsContextBeforeDrawing = YES;
self.userLabel.contentMode = UIViewContentModeRedraw;




I suspect the issue is not with the text attribute. I suspect the problem is that you are adding a new UILabel to the reusable UITableViewCell instead of reusing the old UILabel.



All Articles