【问题标题】:Underline part of a string using NSMutableAttributedString in iOS 8 is not working在 iOS 8 中使用 NSMutableAttributedString 的字符串的下划线部分不起作用
【发布时间】:2014-11-25 23:40:09
【问题描述】:

我尝试在字符串的一部分下划线,例如,'test string' 字符串中的 'string' 部分。我正在使用NSMutableAttributedString,我的解决方案在iOS7 上运行良好。

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
        initWithString:@"test string"];
[attributedString addAttribute:NSUnderlineStyleAttributeName
                         value:@(NSUnderlineStyleSingle)
                         range:NSMakeRange(5, 6)];
myLabel.attributedText = attributedString;

问题是我的解决方案不再适用于iOS8。在花了一个小时测试NSMutableAttributedString 的多个变体之后,我发现这个解决方案仅在范围以 0 开头(长度可以不同)时才有效。这是什么原因?我该如何解决这个问题?

【问题讨论】:

标签: ios objective-c iphone ios8 nsmutableattributedstring


【解决方案1】:

更新: 通过调查这个问题:Displaying NSMutableAttributedString on iOS 8我终于找到了解决办法!

您应该在字符串的开头添加 NSUnderlineStyleNone。

Swift 4.2(none 已删除):

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]))

目标-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"]];

这种方法的另一个好处是没有任何范围。非常适合本地化字符串。

好像是苹果的bug :(

【讨论】:

  • 我认为它可以工作,但不幸的是我在 7.1 模拟器中运行了该应用程序......仍然无法在 iOS8 上工作。但是避开范围非常好,谢谢!
  • 说实话,我没有在 iOS 8 上测试过我的代码。但现在我已经完成了,终于找到了解决方案。
  • 谢谢。这真的节省了我的时间!
  • 添加后如何去掉下划线
  • @JeremyPiednoel,非常感谢!更新了 Swift 4.2 的答案。
【解决方案2】:

我发现如果你将 UnderlineStyleNone 应用到整个字符串,你就可以有选择地将下划线应用到从中间开始的部分:

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
}

【讨论】:

  • 添加后如何去掉下划线
【解决方案3】:
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];

它对我有用

【讨论】:

    【解决方案4】:

    现在是 2018 年 9 月,所以这个答案与 iOS8 无关,但它仍然与字符串的下划线部分有关。

    这是一个 Swift 4 扩展,它在已组合的 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)
        }
    }
    

    用法:myAttributedString.underline(term: "some term")

    【讨论】:

      【解决方案5】:

      Swift 5 版本 @Joss 的答案几乎没有修改,通过添加返回的 NSMutableAttributedString,因为没有它我无法使用原始解决方案。

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

      用法:

       let myUnderLinedText = "Hello World"
       let underLinedMutableString =  NSMutableAttributedString(string: myUnderLinedText, attributes: titleAttributes).underline(term: myUnderLinedText)
      

      【讨论】:

        【解决方案6】:
        let values = NSMutableAttributedString(string: "**YourString**")
        let range = NSRange(location: 0, length: values.length)
        values.addAttribute(.underlineStyle, value: 1, range: range)
        

        这将使字符串带有下划线样式,您也可以替换 .underlinestyle 并使用 .link 将其显示为蓝色的超链接

        【讨论】:

          【解决方案7】:

          我在操场/模拟器中使用了以下扩展(使用 exidy 的功能),效果很好,您可以根据需要更改/添加属性

           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"])
          

          【讨论】:

            【解决方案8】:

            为下划线属性添加颜色:​​​​

            [attributedString addAttribute:NSUnderlineColorAttributeName
                                 value:[UIColor redColor]
                                 range:NSMakeRange(5, 6)];
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-04-04
              • 2019-04-21
              • 2021-02-11
              • 1970-01-01
              • 1970-01-01
              • 2020-05-11
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多