I have user input which can contain markdown or not. I want to show the user input on screen with rendered markdown. For some reason, I want to add my own static string which does not contain markdown to the end of the user input in the blue color.
It worked when I didn't used markdown. My guess is that Data is changing the original range, which makes my code invalid.
This is my code:
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)
)
This crashes with this error:
"NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds"
I did check out the methods on Data, but none of them returns an NSRange. How can I make my code work? Markdown does not support colored text :(.
For clarity of the explanation, let's do a little change:
->
The issue is that
newStringis different fromreplacedMessageText.string, because the Markdown tags (here it's*) have been interpreted and removed. You can see it by printingreplacedMessageText.string. So in your case, the range of the trailing is wrong (it's length is too big), hence the error. If you had reversedtrailingandleading, it would have worked with your sample case, but you would have seen part ofleadingcolored.Instead, you can do:
As a note (it's not your case, but if someone encounter the issue), if you have a Markdown tag that starts on
leadingand ends ontrailing, it won't be rendered.Unrelated:
newString.data(using: .utf8)!can be done withData(newString.utf8), no need to force unwrap.