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

查看:99
本文介绍了未通过绑定调用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.

请注意,之前曾有人问过这个问题,但如果没有回答,则将其标记为正确回答:

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代码中区分字符串的模型更新和textview更新.我在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天全站免登陆