向降价 NSAttributedString 添加属性超出范围

Adding attribute to markdown NSAttributedString goes out of bounds

我有用户输入,可以包含降价或不包含降价。我想在屏幕上显示带有渲染降价的用户输入。出于某种原因,我想将我自己的不包含 markdown 的静态字符串添加到蓝色用户输入的末尾

当我没有使用 markdown 时它起作用了。我的猜测是 Data 正在更改原始范围,这使我的代码无效。

这是我的代码:

let trailing = "I MUST be blue :)"
let newString = "some *user* input" + trailing
let data = newString.data(using: .utf8)!
let replacedMessageText = try! NSMutableAttributedString(markdown: data)

replacedMessageText.addAttribute(
    NSAttributedString.Key.foregroundColor,
    value: UIColor.blue,
    // Here I want to find the range of my trailing static text
    range: (newString as NSString)
        // This line is probably wrong...
        .range(of: trailing, options: .backwards)

)

此崩溃并出现此错误:

"NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds"

我确实查看了 Data 上的方法,但其中 none 个 returns 一个 NSRange。我怎样才能使我的代码工作? Markdown 不支持彩色文本:(.

为了解释清楚,我们做一点改动:

let trailing = "I MUST be blue :)"
let newString = "some *user* input" + trailing

->

let trailing = "I MUST be blue :)"
let leading = "some *user* input"
let newString = leading + trailing

问题是 newString 不同于 replacedMessageText.string,因为 Markdown 标签(这里是 *)已被解释和删除。打印replacedMessageText.string就可以看到了。 所以在你的情况下,尾随的范围是错误的(它的长度太大),因此是错误的。 如果您颠倒了 trailingleading,它会适用于您的示例案例,但您会看到 leading 的一部分是彩色的。

相反,您可以这样做:

let final = NSMutableAttributedString()
let leadingAttrStr = try NSAttributedString(markdown: Data(leading.utf8))
let trailingAttrStr = NSAttributedString(string: trailing, attributes: yourBlueAttributes)
final.append(leadingAttrStr)
final.append(trailingAttrStr)

请注意(这不是你的情况,但如果有人遇到这个问题),如果你有一个以 leading 开始并以 trailing 结束的 Markdown 标签,它不会渲染。

无关: newString.data(using: .utf8)!可以用Data(newString.utf8)完成,不需要强制解包。