是否可以通过编程方式绑定两个关键路径以在 Cocoa 中设置连续更新?

Is it possible to programmatically bind two key paths setting continuous updates in Cocoa?

在 macOS Cocoa 应用程序中,如果我有两个 NSSlider 对象,我可以以编程方式设置以下绑定:

@IBOutlet weak var firstSlider: NSSlider!
@IBOutlet weak var secondSlider: NSSlider!

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application

    self.firstSlider.bind(NSBindingName.init(rawValue: "value"), to: self.secondSlider, withKeyPath: "value", options: [NSBindingOption.continuouslyUpdatesValue : true])
}

这有效,但不是持续更新,除非我在界面构建器的检查器中为滑块设置了连续复选框。我的问题是我想设置其他不公开连续设置的属性之间的绑定,特别是两个 NSTableColumn 实例。是否可以通过在绑定代码中设置一个选项来连续绑定?

对您的问题的简短回答是否定的,这是不可能的。正如您已经发现的那样,您应该只使用自己的 KVO 代码。

更长的答案如下:

从根本上说,问题有两个方面:NSTableColumn 没有 continuous 属性。有 类 可以(例如 NSControlNSCell),但 NSTableColumn 不会继承这些。从技术上讲,这个 属性 旨在确定控件是否将其 action 方法连续发送到其目标 ,而不是专门针对绑定,尽管它也会影响绑定行为。

.continuouslyUpdatesValue 绑定选项的含义略有不同。它用于确定绑定值是在用户交互期间连续更新还是仅在 UI 元素放弃其响应者状态(即用户交互停止)时更新。这主要用于文本 field/view 绑定。

不幸的是,NSTableColumn不能真正成为响应者,至少在传统意义上是这样。此选项对 NSTableColumnwidth.

的绑定没有影响

令人困惑的是,此选项 对来自 NSSlider 的绑定没有影响。相反,如果 NSSlidercontinuous 属性 是 false,它将始终只更新鼠标向上的绑定,即使 .continuouslyUpdatesValue 选项在绑定上设置。相反,如果 NSSlidercontinuous 属性 是 true,它将始终不断更新绑定的值,即使 .continuouslyUpdatesValue 选项在绑定上设置为 false。

一些使用调试器的挖掘解释了这种行为。 NSSlider 始终更新其绑定值作为将其操作发送到其目标的副作用(无论 .continuouslyUpdatesValue 选项如何)。这解释了为什么它的 continuous 属性 完全决定了它的行为。

另一方面,当 NSTableColumn 更新其 width 属性 并因此在其宽度改变时连续发出 KVO 通知,它仅更新其 width binding 作为发布它在宽度变化时发布的 columnDidResizeNotification 的副作用。此通知仅在调整大小结束时发布,而不是在调整大小期间发布。因此,NSTableColumn 只会在调整大小结束时更新其绑定。