iosobjective-ciphoneios8nsmutableattributedstring

Underline part of a string using NSMutableAttributedString in iOS 8 is not working


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?


Solution

  • 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 :(