gpt4 book ai didi

ios - 在 UITextView 中拆分段落并保存范围

转载 作者:行者123 更新时间:2023-11-28 05:40:50 29 4
gpt4 key购买 nike

我正在尝试使用我在下面键入的代码将段落拆分为一组组件。不过,我在使用 Ranges 元素时遇到了问题。我的问题是,如果用户多次键入一个字符串,它会返回第一个时间范围,而不是我想要的那个。

示例:
第1款:香蕉
第二款:苹果
第三段:香蕉​​

第 1 段和第 3 段都将具有第 1 段的范围。解决此问题的更明智的方法是什么?

lazy var models: [ParagraphModel] = []

struct ParagraphModel {
let text: String
let range: Range<String.Index>
}

func getParagraphs(){
let components = textView.text.components(separatedBy: "\n")

let models = components.compactMap { component -> ParagraphModel? in
if let range = textView.text.range(of: component) {
return ParagraphModel(text: component, range: range)
}
return nil
}
self.models = models
}

来自@Rob 的更新代码:

func getParagraphModel() {
guard let text = noteContents.text else { return }

var currentModels: [ParagraphModel] = []
text.enumerateSubstrings(in: text.startIndex..., options: .byParagraphs) { substring, range, _, stop in
if let substring = substring, !substring.isEmpty,
let textRange = self.noteContents.text.range(of: substring)
{
currentModels.append(ParagraphModel(text: substring, range: textRange))
}
}
self.models = currentModels
}

当键入示例文本时,控制台的打印输出是:

[Project.ViewController.ParagraphModel(text: "Banana", range: Range(Swift.String.Index(_rawBits: 0)..<Swift.String.Index(_rawBits: 393216))), Project.ViewController.ParagraphModel(text: "Apple", range: Range(Swift.String.Index(_rawBits: 458752)..<Swift.String.Index(_rawBits: 786432))), Project.ViewController.ParagraphModel(text: "Banana", range: Range(Swift.String.Index(_rawBits: 0)..<Swift.String.Index(_rawBits: 393216)))]

最佳答案

您的代码片段中的问题是您总是会找到目标字符串的第一次出现。因此,当它搜索第三段“Banana”时,它将找到该字符串的第一次出现。

我建议使用 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)))
]

或者,如果 ParagraphModel 中的 range 是一个 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)
]

关于ios - 在 UITextView 中拆分段落并保存范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56814207/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com