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

后端 未结 7 545
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-13 12:11

I try to underline part of a string, for example, a \'string\' part in \'test string\' string. I\'m using NSMutableAttributedString and my sol

相关标签:
7条回答
  • 2020-12-13 12:33

    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
    }
    
    0 讨论(0)
  • 2020-12-13 12:35

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

    0 讨论(0)
  • 2020-12-13 12:42

    It's September 2018, so this answer is not about iOS8 but it still relates to underlining part of a string.

    Here is a Swift 4 extension that underlines a given term within an already composed myAttributedString

    extension NSMutableAttributedString {
    
        func underline(term: String) {
    
            guard let underlineRange = string.range(of: term) else {
    
                return
            }
    
            let startPosition = string.distance(from: term.startIndex, to: underlineRange.lowerBound)
            let nsrange = NSRange(location: startPosition, length: term.count)
    
            addAttribute(
                .underlineStyle,
                value: NSUnderlineStyle.styleSingle.rawValue,
                range: nsrange)
        }
    }
    

    Usage: myAttributedString.underline(term: "some term")

    0 讨论(0)
  • 2020-12-13 12:45
    NSMutableAttributedString *signUpString = [[NSMutableAttributedString alloc] initWithString:@"Not a member yet?Sign Up now"];
    
    [signUpString appendAttributedString:[[NSAttributedString alloc] initWithString:@" "attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)}]];
    
    [signUpString addAttributes: @{NSForegroundColorAttributeName:UIColorFromRGB(0x43484B),NSUnderlineStyleAttributeName:[NSNumber numberWithInteger:NSUnderlineStyleSingle]} range:NSMakeRange(17,11)];
    
    signUpLbl.attributedText = [signUpString copy];
    

    It worked for me

    0 讨论(0)
  • 2020-12-13 12:48

    Add color for underline attribute:​​​

    [attributedString addAttribute:NSUnderlineColorAttributeName
                         value:[UIColor redColor]
                         range:NSMakeRange(5, 6)];
    
    0 讨论(0)
  • 2020-12-13 12:49

    I used the following extension (using exidy's function) in playground/simulator and it worked fine , you may change/add attributes depending on your needs

     extension NSMutableAttributedString
    {
    
    
        func changeWordsColour(terms:[NSString])
    {
        let string = self.string as NSString
        self.addAttribute(NSForegroundColorAttributeName, value: UIColor.brownColor(), range: NSMakeRange(0, self.length))
        for term in terms
        {
            let underlineRange = string.rangeOfString(term as String)
            self.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: underlineRange)
    
        }
    }
    }
    
     let myStr = NSMutableAttributedString(string: "Change Words Colour")
     myStr.changeWordsColour(["change","Colour"])
    
    0 讨论(0)
提交回复
热议问题