使用iOS 8中的NSMutableAttributedString对字符串的下划线部分无效

时间:2014-10-01 07:24:11

标签: ios objective-c iphone ios8 nsmutableattributedstring

我尝试为字符串的一部分加下划线,例如,' 字符串'参与' 测试字符串'串。我使用NSMutableAttributedString并且我的解决方案在iOS7上运行良好。

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

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

7 个答案:

答案 0 :(得分:124)

<强>更新 通过调查这个问题: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"]];

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

好像是苹果虫:(

答案 1 :(得分:17)

我发现如果你将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
}

答案 2 :(得分:6)

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

它对我有用

答案 3 :(得分:2)

现在是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")

答案 4 :(得分:1)

@Joss答案的

Swift 5版本,通过添加返回的NSMutableAttributedString进行了少量修改,因为没有它,我将无法使用原始解决方案。

import React, { Component } from "react";
import { Select, MenuItem } from "@material-ui/core";

class MySelect extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: 0,
      open: false,
      width: null
    };

    this.selectRef = React.createRef();
  }

  componentDidMount() {
    const width = this.selectRef.current.clientWidth;
    this.setState(
      {
        width: width
      },
      () => console.log(this.state.width)
    );
  }

  render() {
    return (
      <div ref={this.selectRef}>
        <Select
          fullWidth
          ref={this.selectRef}
          onChange={event => {
            this.setState({
              value: event.target.value
            });
          }}
          value={this.state.value}
        >
          <MenuItem value={0}>Zero</MenuItem>
          <MenuItem value={1}>One</MenuItem>
          <MenuItem value={2}>Two</MenuItem>
          <MenuItem value={3}>Three</MenuItem>
          <MenuItem value={4}>Four</MenuItem>
        </Select>
      </div>
    );
  }
}

export default MySelect;

用法:

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
    }   
}

答案 5 :(得分:0)

我在游乐场/模拟器中使用了以下扩展(使用exidy&#39; s功能)并且工作正常,您可以根据需要更改/添加属性

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

答案 6 :(得分:-2)

为下划线属性添加颜色:

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