Answer the question
In order to leave comments, you need to log in
How to output correct NSRange with NSAttributedString if NSAttributedString is initialized with Data(HTML)?
Hello!
There is a UITextView in which the text is assigned via .attributedText.
NSAttributedString is initialized with Data (we take it from reading the file in which html is). When initializing NSAttributedString, we specify documentType - html.
var HTMLdata:Data?{
didSet{
guard let data = self.HTMLdata else {return}
do{
let attributed = try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType:NSAttributedString.DocumentType.html], documentAttributes: nil)
textView.attributedText = attributed
}catch{
return
}
}
}
<p class=main-text><a name="link5"></a>
<span class=main-text-span>Название</span> абзаца</p>
let range = attributed.string.range(of: #"<a name="link5"></a>"#) // -> nil
Answer the question
In order to leave comments, you need to log in
As an option, use regex, with which you can find what is written in from the displayed text (we are looking for a String initialized with data (html), that is, we see all the tags), and look for this text in attributed.string:<p>
//1
private func getRangeFor(attributedString:String,aValue:String) -> NSRange?{
guard let aWord = self.findAWords(aValue: aValue),let foundRange = attributedString.range(of: aWord) else {return nil}//ищем aWord - то, что записано в <p>, затем ищем уже range в attributedString(отрендеренный HTML)
return NSRange(foundRange, in: attributedString)
}
//2
private func findAWords(aValue:String) -> String?{
guard let data = self.HTMLdata,let str = String(data: data, encoding: .utf8) else {return nil}
let pattern = #"<p class=main-text><a name="\#(aValue)"></a>\n<span class=main-text-span>(?<paragraph>.+)</span>"#
let regexRange = NSRange(location: 0, length: str.utf16.count)
let regex = try! NSRegularExpression(pattern: pattern)
let regexResult = regex.firstMatch(in: str, options: [], range: regexRange)
guard let matchedWordRange = regexResult?.range(withName: "paragraph"), let wordRange = Range(matchedWordRange, in: str) else {return nil}
return String(str[wordRange]) //вернет слово (Название), нужно дописать regex, чтобы была вторая группа - слово ( абзаца)
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question