【发布时间】:2017-08-16 05:02:31
【问题描述】:
我有一个自定义的 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: 方法,其他一切正常,并且自动拼写功能返回。我只需要小心不要触发导致缩短文本的更改,因为它会触发属性超出范围错误(首先是我的自定义方法的原始原因。)
显然,Apple 对insertText:replacementRange: 的实现比我的要多得多。我在[self checkTextInRange...]、[self checkTextInSelection:] 等上尝试了多种变体。它们都没有恢复正常的功能。
搜索 Apple 的文档并不能帮助我指出我的方法中遗漏的导致拼写检查中断的内容。任何指针或想法将不胜感激!
提前致谢!
编辑:以下是我的 NSTextStorage 提供的一些行为示例。 (| 代表插入符号)
开始于:
* item
* |
如果我按回车键,我会得到以下结果(删除*<space>):
* item
|
另一个例子,如果启用“更改跟踪”:
this is thee| time
如果我点击删除:
this is the|{--e--} time
如您所见,单次击键可能会导致从文本中添加或删除多个字符。
编辑 2:仅供参考——当在文档末尾按回车键时发生缩短时,我遇到的属性超出范围的问题会发生——NSTextview 尝试设置新的段落样式才发现文档比预期的要短。我找不到改变范围 NSTextview 目标的方法。
【问题讨论】:
-
如何修改文本存储?你打电话给
beginEditing、endEditing、edited:range:changeInLength:什么的? -
是的——所有三个。 NSTextStorage 中的所有内容都可以完美运行(至少在我几个月和几个月的使用期间)。我能够找到的唯一问题是拼写问题,如上已修复 - 禁用自定义
insertText:replacementRange:(但仍使用我的自定义 NSTextStorage)并返回拼写。 -
显然您无法通过替换
insertText:replacementRange:来修复属性超出范围错误。错误来自哪里? -
键入时的一种可能行为是,按回车键实际上可以删除插入点之前的字符,导致字符串比用户按回车时短。在 Apple 的
insertText...方法中的某个时刻,它会从 NSTextStorage 请求属性,期望字符串比实际更长。我尝试发回虚假属性,但这使问题更加复杂。通过覆盖该方法,我遗漏了损坏的部分,但显然也遗漏了我想要的东西.... ;) -
在
NSTextStorage和NSTextStorageDelegate的哪些方法中修改文字?
标签: objective-c macos cocoa spell-checking nstextview