I try to underline part of a string, for example, a 'string' part in 'test string' string. I'm using NSMutableAttributedString
and my solution was working well on iOS7
.
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"test string"]; [attributedString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(5, 6)]; myLabel.attributedText = attributedString;
The problem is that my solution is not working in iOS8
anymore. After spending an hour on testing multiple variants of NSMutableAttributedString
, I found out that this solution works only when range starts with 0 (length can differ). What is the reason for that? How can I workaround this?
To make the text on UILabel underlined we will need to use the NSMutableAttributedString together with NSUnderlineStyleAttributeName. The Swift code snippet below demonstrates how to create a new UILabel programmatically and then use the NSMutableAttributedString to underline the text on the label.
How do I underline a button in Swift? swift 3/4/5 Select button or label title as Attributed. Select range of text which you want to underline. Right click and choose Font then select underline.
An NSAttributedString object manages character strings and associated sets of attributes (for example, font and kerning) that apply to individual characters or ranges of characters in the string. An association of characters and their attributes is called an attributed string.
Update: By investigating this question: Displaying NSMutableAttributedString on iOS 8 I finally found the solution!
You should add NSUnderlineStyleNone at the beginning of the string.
Swift 4.2 (none
was removed):
let attributedString = NSMutableAttributedString() attributedString.append(NSAttributedString(string: "test ", attributes: [.underlineStyle: 0])) attributedString.append(NSAttributedString(string: "s", attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue])) attributedString.append(NSAttributedString(string: "tring", attributes: [.underlineStyle: 0]))
Objective-C:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init]; [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"test " attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)}]]; [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"s" attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle), NSBackgroundColorAttributeName: [UIColor clearColor]}]]; [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"tring"]];
Another bonus of such approach is absence of any ranges. Very nice for localized strings.
Seems like it is Apple bug :(
I found that if you apply UnderlineStyleNone to the whole string you can then selectively apply underline to a part that starts in the middle:
func underlinedString(string: NSString, term: NSString) -> NSAttributedString { let output = NSMutableAttributedString(string: string) let underlineRange = string.rangeOfString(term) output.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleNone.rawValue, range: NSMakeRange(0, string.length)) output.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: underlineRange) return output }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With