NSTextView textDidChange 未通过绑定调用 [英] NSTextView textDidChange not called through binding

查看:17
本文介绍了NSTextView textDidChange 未通过绑定调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 NSTextViews,我需要在其中跟踪文本的当前端点以放置界面元素.

I have NSTextViews where I need to track the current end point of the text to place interface elements.

我将模型字符串绑定到文本视图上的 NSBindingName.value.

I bind a model string to NSBindingName.value on the text view.

编辑文本时,我会在

func textDidChange(_ notification: Notification)

...作为 NSTextView 的委托.

...as a delegate to the NSTextView.

但是,如果我的模型是字符串更新的源,则永远不会调用此委托方法,即使 NSTextView 中的文本已正确更新.

However, if my model is the source of a string update, this delegate method is never called, even though the text is correctly updated in the NSTextView.

那么,我做错了什么,绑定更改应该调用 textDidChange 吗?

So, am I doing something wrong and the bound change should call textDidChange?

如果不是,这是一个错误或设计使然,我是否应该只观察并手动更新值并通过自己的委托方法调用?失去绑定的优雅似乎是一种耻辱.

If not, and this is a bug or by design, should I just be observing and manually updating values and calling by own delegate method? It seems a shame to lose the elegance of the binding.

请注意,这之前已经被问过,但如果不是,则标记为正确回答:NSTextView textDidChange/didChangeText 未调用绑定

Please note that this has been asked before, but marked as correctly answered when it is not: NSTextView textDidChange/didChangeText not called for bindings

推荐答案

NSTextView 方法 didChangeText 在绑定更新文本时调用,而不是文本视图更新模型时调用.

The NSTextView method didChangeText is not called when a binding updates the text, rather than the text view updating the model.

didChangeText 是绑定更新的.如果您覆盖它并且不调用 super,则绑定将被破坏.didChangeText 调用委托方法 textDidChange.

didChangeText is the source of the binding update. If you override it and don't call super, the binding is broken. didChangeText calls the delegate method textDidChange.

不幸的是,在 NSTextView 更新过程中也很晚才调用 didChangeText - 在布局和存储委托调用之后.

Unfortunately, didChangeText is also called rather late in the NSTextView update process - after the layout and storage delegate calls.

这让我很沮丧,因为我需要在调用我的委托之前更改模型 - 我正在使用另一个视图开始单独计算 NSTableView 行高.如果这些是在模型更新之前完成的,我就会得到错误的高度.

This scuppered me because I needed the model to change before I called my delegate - I was kicking off separate calculations for NSTableView row heights with another view. If these were done before the model update I got the wrong heights.

我发现无法从 NSTextView 代码中区分模型和文本视图对字符串的更新.我在 didProcessEditing 中捕获了对字符串的所有更新作为 NSTextStorage 委托.

I found no way of differentiating between model and textview updates to the string from within the NSTextView code. I caught all updates to the string in didProcessEditing as an NSTextStorage delegate.

func textStorage(_ textStorage: NSTextStorage,
                 didProcessEditing editedMask: NSTextStorageEditActions,
                 range editedRange: NSRange,
                 changeInLength delta: Int)
{
    if editedMask.contains(.editedCharacters) {
        textStringDidChange = true
    }
}

我只是在这里设置了一个标志,因为如果他们试图以任何方式更新 NSTextView,在这里调用我的委托就会崩溃.然后我在以下 NSLayoutManagerDelegate 调用中使用了这个标志:

I just set a flag here, because calls to my delegate here would crash if they tried to update the NSTextView in any way. I then used this flag in a following NSLayoutManagerDelegate call:

func layoutManagerDidInvalidateLayout(_ sender: NSLayoutManager)
    {
        if textStringDidChange {
            delegate?.textDidChange?(Notification(name: .init("")))
            textStringDidChange = false
        }
    }

didChangeText 在这些委托调用之后的某个时间被调用.因此,我不得不让文本视图初始化更改两次调用我的委托.它效率低下,但我发现没有办法过滤掉它.

didChangeText is called sometime after these delegate calls. Therefore I had to make do with having text-view initialised changes calling my delegate twice. It is inefficient but I found no way of filtering that out.

这篇关于NSTextView textDidChange 未通过绑定调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆