Проблема в вашем фрагменте кода заключается в том, что вы всегда будете находить первое вхождение целевой строки.Поэтому, когда он ищет третий абзац «Банан», он находит первое вхождение этой строки.
Я бы предложил text.enumerateSubstrings(in:options:_:)
, чтобы получить диапазоны абзацев в пределах text
.Это будет перечислять подстроки и их соответствующие диапазоны, что позволит вам избежать поиска текста самостоятельно, избегая проблем, которые могут возникнуть, если одна и та же строка появляется несколько раз.
Таким образом:
func getParagraphs() {
guard let textView = textView, let text = textView.text else { return }
models = []
text.enumerateSubstrings(in: text.startIndex..., options: .byParagraphs) { substring, range, _, _ in
guard let substring = substring, !substring.isEmpty else {
return
}
self.models.append(ParagraphModel(text: substring, range: range))
}
}
Топроизводит:
[
MyApp.ParagraphModel(text: "Paragraph 1: Banana", range: Range(Swift.String.Index(_rawBits: 0)..<Swift.String.Index(_rawBits: 1245184))),
MyApp.ParagraphModel(text: "Paragraph 2: Apple", range: Range(Swift.String.Index(_rawBits: 1376256)..<Swift.String.Index(_rawBits: 2555904))),
MyApp.ParagraphModel(text: "Paragraph 3: Banana", range: Range(Swift.String.Index(_rawBits: 2686976)..<Swift.String.Index(_rawBits: 3932160)))
]
Или, если range
в ParagraphModel
было UITextRange
, вы бы сделали:
func getParagraphs() {
guard let textView = textView, let text = textView.text else { return }
models = []
text.enumerateSubstrings(in: text.startIndex..., options: .byParagraphs) { substring, range, _, stop in
let nsRange = NSRange(range, in: text)
if let substring = substring,
!substring.isEmpty,
let start = textView.position(from: textView.beginningOfDocument, offset: nsRange.location),
let end = textView.position(from: start, offset: nsRange.length),
let textRange = self.textView.textRange(from: start, to: end)
{
self.models.append(ParagraphModel(text: substring, range: textRange))
}
}
}
Производство:
[
MyApp.ParagraphModel(text: "Paragraph 1: Banana", range: <_UITextKitTextRange: 0x6000037983e0> (0, 19)F),
MyApp.ParagraphModel(text: "Paragraph 2: Apple", range: <_UITextKitTextRange: 0x600003798260> (21, 18)F),
MyApp.ParagraphModel(text: "Paragraph 3: Banana", range: <_UITextKitTextRange: 0x600003799f20> (41, 19)F)
]