Cocoa Text - 即时刷新文本

发布于 2024-11-17 00:33:34 字数 797 浏览 2 评论 0原文

在我正在开发的应用程序中,用户输入纯文本,应用程序通过将其转换为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尴尬癌患者 2024-11-24 00:33:34

我认为您对 NSTextView 的工作原理有轻微的误解。用户永远不会输入“纯字符串”,NSTextView 的数据存储始终NSTextStorage 对象,它是 NSTextStorage 的子类>NSMutableAttributedString。

您需要做的是向用户正在编辑的现有属性字符串添加/删除属性,而不是替换整个字符串。

您也不应该更改 -textDidChange: 委托方法中的字符串,因为从该方法更改字符串可能会导致另一个更改通知。

相反,您应该实现委托方法 -textStorageDidProcessEditing:。每当文本更改时都会调用此函数。然后您可以像这样修改字符串:

- (void)textStorageDidProcessEditing:(NSNotification*)notification
{
    //get the text storage object from the notification
    NSTextStorage* textStorage = [notification object];

    //get the range of the entire run of text
    NSRange aRange = NSMakeRange(0, [textStorage length]);

    //for example purposes, change all the text to yellow

    //remove existing coloring
    [textStorage removeAttribute:NSForegroundColorAttributeName range:aRange];

    //add new coloring
    [textStorage addAttribute:NSForegroundColorAttributeName 
                        value:[NSColor yellowColor] 
                        range:aRange];
}

I think you have a slight misconception of how an NSTextView works. The user never enters a "plain string", the data store of an NSTextView is always an NSTextStorage object, which is a subclass of NSMutableAttributedString.

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:

- (void)textStorageDidProcessEditing:(NSNotification*)notification
{
    //get the text storage object from the notification
    NSTextStorage* textStorage = [notification object];

    //get the range of the entire run of text
    NSRange aRange = NSMakeRange(0, [textStorage length]);

    //for example purposes, change all the text to yellow

    //remove existing coloring
    [textStorage removeAttribute:NSForegroundColorAttributeName range:aRange];

    //add new coloring
    [textStorage addAttribute:NSForegroundColorAttributeName 
                        value:[NSColor yellowColor] 
                        range:aRange];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文