我有我需要跟踪文本的当前终点放置界面元素NSTextViews。
我的模型字符串绑定到NSBindingName.value上的文本视图。
当编辑文本我更新我的界面元素的位置
func textDidChange(_ notification: Notification)
......作为一个代表到NSTextView。
但是,如果我的模型是一个字符串更新的来源,此委托方法不会被调用,即使文本在NSTextView正确更新。
所以,我是不是做错了什么和被捆绑的变化应该调用textDidChange?
如果不是,这是一个错误或设计,应我只是观察和手动更新值,并通过自己的委托方法调用?这似乎是一个耻辱,失去了约束力的风采。
请注意,这已被问过,但标记为回答正确时,它不是:NSTextView textDidChange/didChangeText not called for bindings
当绑定更新的文字,而不是更新的模型从文本视图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在这些委托来电之后有时称为。所以我只好凑合着用具有文本视图初始化的变化呼唤我的代表两次。这是低效的,但我没有发现过滤说出来的方式。