NSTextView textDidChange不是通过所谓的结合

问题描述 投票:0回答:1

我有我需要跟踪文本的当前终点放置界面元素NSTextViews。

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

当编辑文本我更新我的界面元素的位置

func textDidChange(_ notification: Notification)

......作为一个代表到NSTextView。

但是,如果我的模型是一个字符串更新的来源,此委托方法不会被调用,即使文本在NSTextView正确更新。

所以,我是不是做错了什么和被捆绑的变化应该调用textDidChange?

如果不是,这是一个错误或设计,应我只是观察和手动更新值,并通过自己的委托方法调用?这似乎是一个耻辱,失去了约束力的风采。

请注意,这已被问过,但标记为回答正确时,它不是:NSTextView textDidChange/didChangeText not called for bindings

cocoa appkit nstextview
1个回答
0
投票

当绑定更新的文字,而不是更新的模型从文本视图NSTextView方法didChangeText不叫。

didChangeText是绑定更新的来源。如果忽略它,不叫超,结合被打破。 didChangeText调用委托方法textDidChange。

不幸的是,didChangeText也被称为较晚的NSTextView更新过程 - 布局和存储代表来电之后。

这泡影我,因为我需要的模式改变之前,我打电话给我的委托 - 我被踢了用另一种观点NSTableView的行高度分别计算。如果这些模型更新之前我做了错误的高度。

我发现没有从NSTextView代码中的模型和TextView的更新区分字符串的方法。我抓住所有更新到didProcessEditing的字符串作为NSTextStorage委托。

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

我只是设置一个标志,在这里,因为在这里我代表电话会崩溃,如果他们试图以任何方式来更新NSTextView。然后,我在下面的NSLayoutManagerDelegate呼叫使用此标志:

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

didChangeText在这些委托来电之后有时称为。所以我只好凑合着用具有文本视图初始化的变化呼唤我的代表两次。这是低效的,但我没有发现过滤说出来的方式。

© www.soinside.com 2019 - 2024. All rights reserved.