Reputation: 12132
I've looked at ~10 questions on SO and am still coming up short.
I have a multiline UILabel (created in Interface Builder, numberOfLines set to 0) which renders normally like this:
I want to be underline "Terms of Service" and "Privacy Policy", so I added this code:
NSString *text = self.agreement.text;
NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:text];
NSRange privacyRange = [text rangeOfString:@"privacy policy" options:NSCaseInsensitiveSearch];
[aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:privacyRange];
NSRange tosRange = [text rangeOfString:@"terms of service" options:NSCaseInsensitiveSearch];
[aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:tosRange];
self.agreement.attributedText = aString;
But the result looks like this:
What do I need to do so both lines appear, with the appropriate ranges underlined?
Also, I'd prefer not to use a 3rd Party Library like OHAttributedLabel or TTTAttributedLabel since this is the only place in my app where I need to underline a piece of text.
What I've Tried
sizeToFit
after setting the attributed textnumberOfLines
and lineBreakMode
in codeSascha asked me to upload two screenshots with the background colors set to something other than clear. Oddly enough, everything shows up as expected! Not sure what to make of this or what this is telling us.
Upvotes: 7
Views: 5468
Reputation: 5380
First create attributed text as you did:
NSString *text = self.agreement.text;
NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:text];
NSRange privacyRange = [text rangeOfString:@"privacy policy" options:NSCaseInsensitiveSearch];
[aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:privacyRange];
NSRange tosRange = [text rangeOfString:@"terms of service" options:NSCaseInsensitiveSearch];
[aString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:tosRange];
Assign font you'd like to use to your attributed string:
[aString addAttribute:NSFontAttributeName value:self.agreement.font range:(NSRange){0, aString.length}];
self.agreement.attributedText = aString;
Define your label to be multiline:
self.agreement.numberOfLines = 0;
self.agreement.lineBreakMode = NSLineBreakByWordWrapping;
Estimate your label size:
CGRect myLabelRect = [aString boundingRectWithSize:CGSizeMake(self.view.frame.size.width, INT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
Use estimated size when adding label to view:
self.agreement.frame = CGRectMake(self.view.frame.size.width / 2 - myLabelRect.size.width / 2,
0,
myLabelRect.size.width,
myLabelRect.size.height);
[self.view addSubview:self.agreement];
Upvotes: 3
Reputation: 12132
So yesterday, based on tsafrir's comments (iOS 7 bug, should be fixed in 7.1), I broke the two lines into two labels and moved on.
Then, SashaHameister recommended I see what happens when I apply a non-clear background-color. So I deleted the top label, added the text to the second label so it was two lines, change the background-color, and both lines rendered fine. I thought that was the solution (even though it wouldn't work because I needed a clear background).
After that, I tested changing it back to clear, and it still worked for me. It turns out it had something to do with the size of my label. My two line label had a height of ~75, way more than necessary for a two line label at 11pt font. Because of the adjustments I made yesterday (breaking the lines up to two labels), when I copy and pasted the first label's text into the second, the height only ended up being 48px, and that renders just fine.
I still have no idea why this makes such an impact, but if you're having the same problem, chances are your label's height is larger than it needs to be. Try reducing it as much as possible and get it as tight on the actual text as you can.
Upvotes: 0