我有一个自定义的NSTextView子类,还有一个自定义的NSTextStorage组件。NSTextStorage根据上下文修改用户输入的文本。
因为最终文本有可能比用户最初输入的文本短,所以我必须在NSTextView中覆盖insertText:replacementRange
。最小示例为:
- (void) insertText:(id)string replacementRange:(NSRange)replacementRange {
if ([self hasMarkedText]) {
[[self textStorage] replaceCharactersInRange:[self markedRange] withString:string];
} else {
[[self textStorage] replaceCharactersInRange:[self selectedRange] withString:string];
}
[self didChangeText];
}
这在几个月的广泛测试中运行良好……除了禁用自动拼写检查和更正之外。除非我停止打字,移动鼠标,并将焦点从我的应用程序切换到我的应用程序,否则“弯弯曲曲”不会出现在拼写错误的单词下面。几秒钟后,将对整个文本视图进行拼写检查。因为它是在事后发生的,所以自动校正当然是禁用的。
如果我禁用了自定义的insertText:replacementRange:
方法,其他一切都会正常工作,并且自动拼写功能会返回。我只需要小心,不要触发导致文本缩短的更改,因为它会触发属性超出范围的错误(这就是我的自定义方法最初的原因)。
显然,苹果的insertText:replacementRange:
实现比我的要多得多。我已经尝试了[self checkTextInRange...]
,[self checkTextInSelection:]
等的多种变体,它们都没有恢复正常的功能。
搜索Apple的文档并不能帮助我指出我的方法中遗漏了哪些导致拼写检查失败的地方。如有任何建议或想法,我们将不胜感激!
提前感谢!
编辑:下面是我的NSTextStorage提供的各种行为的一些示例。(|
表示插入插入符号)
从以下内容开始:
* item
* |
如果我按下return键,我会得到以下结果(删除*<space>
):
* item
|
另一个例子是,如果启用了“更改跟踪”:
this is thee| time
如果我点击delete:
this is the|{--e--} time
如您所见,单次击键可能会导致在文本中添加或删除多个字符。
EDIT 2:仅供参考--当在文档末尾按return时发生缩写时,我遇到的属性超出范围的问题-- NSTextview尝试设置新的段落样式,结果发现文档比预期的要短。我找不到任何方法来改变NSTextview的目标。
发布于 2018-05-22 22:04:14
(2018-05-30编辑)
更新响应(2018-05-22):
这个问题再次浮出水面,我真的需要弄清楚它。
insertText:replacementRange:
,但它调用[super insertText:replacementRange:]
来利用苹果的幕后工作,使拼写等工作更好地工作。我的自定义方法只需要设置一个布尔值。insertText:replacementRange:
的请求,要求在文本中不存在的部分中添加属性。以前,我会被困在这里,因为我尝试的每件事要么导致崩溃,要么导致苹果的代码重复请求不存在的属性,我尝试用空的距离指针返回假的属性,这似乎使苹果的代码happy://明显返回伪属性满足NSTextView范围* insertText = _invalidRange;返回_invalidAttrs;
这似乎在以前会触发异常或无限循环的各种条件下都有效。
发布于 2017-09-02 12:51:03
我有一个部分的解决方案。
在我的自定义insertText:replacementRange:
方法中,在didChangeText
之前
NSinteger wordCount;
NSOrthography * orthography;
static NSInteger theWordCount;
NSOrthography * orthography;
NSRange spellingRange = <range to check>
NSArray * results = [[NSSpellChecker sharedSpellChecker] checkString:[[self textStorage] string]
range:spellingRange
types:[self enabledTextCheckingTypes]
options:NULL
inSpellDocumentWithTag:0
orthography:&orthography
wordCount:&theWordCount];
if (results.count) {
[self handleTextCheckingResults:results forRange:spellingRange types:[self enabledTextCheckingTypes] options:@{} orthography:orthography wordCount:theWordCount];
}
然而,这是不完整的:
https://stackoverflow.com/questions/45705424
复制相似问题