Cocoa Text - 即时刷新文本
在我正在开发的应用程序中,用户输入纯文本,应用程序通过将其转换为 NSAttributedString 来重新格式化文本,并显示它。这一切都发生在现场。
目前,我正在 NSTextView 的 textDidChange 委托方法上执行以下操作:
- (void)textDidChange:(NSNotification *)notification {
// saving the cursor position
NSInteger insertionPoint = [[[self.mainTextView selectedRanges] objectAtIndex:0] rangeValue].location;
// this grabs the text view's contact as plain text
[self updateContentFromTextView];
// this creates an attributed strings and displays it
[self updateTextViewFromContent];
// resetting the cursor position
self.mainTextView.selectedRange = NSMakeRange(insertionPoint, 0);
}
虽然这大部分有效,但并不理想。文本似乎会闪烁一瞬间(您尤其会注意到拼写错误下的红点),并且当光标之前靠近可见矩形的边缘之一时,滚动位置会重置。就我而言,这是一个非常不受欢迎的副作用。
所以我的问题是:有没有更好的方法来做我想做的事情?
In an app I'm working on, the user inputs plain text, and the app reformats the text by transforming it to an NSAttributedString, and displays it. This all happens live.
Currently, I'm doing the following on my NSTextView's textDidChange delegate method:
- (void)textDidChange:(NSNotification *)notification {
// saving the cursor position
NSInteger insertionPoint = [[[self.mainTextView selectedRanges] objectAtIndex:0] rangeValue].location;
// this grabs the text view's contact as plain text
[self updateContentFromTextView];
// this creates an attributed strings and displays it
[self updateTextViewFromContent];
// resetting the cursor position
self.mainTextView.selectedRange = NSMakeRange(insertionPoint, 0);
}
While this mostly works, it's not ideal. The text seems to blink for a split second (you especially notice it on the red dots under spelling errors), and when the cursor was previously near one of the edges of the visible rect, it the scroll position gets reset. In my case, this is a very much undesirable side-effect.
So my question is: Is there a better way of doing what I'm trying to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您对
NSTextView
的工作原理有轻微的误解。用户永远不会输入“纯字符串”,NSTextView
的数据存储始终是NSTextStorage
对象,它是NSTextStorage
的子类>NSMutableAttributedString。您需要做的是向用户正在编辑的现有属性字符串添加/删除属性,而不是替换整个字符串。
您也不应该更改
-textDidChange:
委托方法中的字符串,因为从该方法更改字符串可能会导致另一个更改通知。相反,您应该实现委托方法
-textStorageDidProcessEditing:
。每当文本更改时都会调用此函数。然后您可以像这样修改字符串:I think you have a slight misconception of how an
NSTextView
works. The user never enters a "plain string", the data store of anNSTextView
is always anNSTextStorage
object, which is a subclass ofNSMutableAttributedString
.What you need to do is add/remove attributes to the existing attributed string that the user is editing, rather than replacing the entire string.
You should also not make changes to the string in the
‑textDidChange:
delegate method, as changing the string from that method can cause another change notification.Instead, you should implement the delegate method
‑textStorageDidProcessEditing:
. This is called whenever the text changes. You can then make modifications to the string like so: