是否可以通过编程方式绑定两个关键路径以在 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
属性。有 类 可以(例如 NSControl
和 NSCell
),但 NSTableColumn
不会继承这些。从技术上讲,这个 属性 旨在确定控件是否将其 action 方法连续发送到其目标 ,而不是专门针对绑定,尽管它也会影响绑定行为。
.continuouslyUpdatesValue
绑定选项的含义略有不同。它用于确定绑定值是在用户交互期间连续更新还是仅在 UI 元素放弃其响应者状态(即用户交互停止)时更新。这主要用于文本 field/view 绑定。
不幸的是,NSTableColumn
不能真正成为响应者,至少在传统意义上是这样。此选项对 NSTableColumn
的 width
.
的绑定没有影响
令人困惑的是,此选项 也 对来自 NSSlider
的绑定没有影响。相反,如果 NSSlider
的 continuous
属性 是 false
,它将始终只更新鼠标向上的绑定,即使 .continuouslyUpdatesValue
选项在绑定上设置。相反,如果 NSSlider
的 continuous
属性 是 true
,它将始终不断更新绑定的值,即使 .continuouslyUpdatesValue
选项在绑定上设置为 false。
一些使用调试器的挖掘解释了这种行为。 NSSlider
始终更新其绑定值作为将其操作发送到其目标的副作用(无论 .continuouslyUpdatesValue
选项如何)。这解释了为什么它的 continuous
属性 完全决定了它的行为。
另一方面,当 NSTableColumn
更新其 width
属性 并因此在其宽度改变时连续发出 KVO 通知,它仅更新其 width
binding 作为发布它在宽度变化时发布的 columnDidResizeNotification
的副作用。此通知仅在调整大小结束时发布,而不是在调整大小期间发布。因此,NSTableColumn
只会在调整大小结束时更新其绑定。
在 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
属性。有 类 可以(例如 NSControl
和 NSCell
),但 NSTableColumn
不会继承这些。从技术上讲,这个 属性 旨在确定控件是否将其 action 方法连续发送到其目标 ,而不是专门针对绑定,尽管它也会影响绑定行为。
.continuouslyUpdatesValue
绑定选项的含义略有不同。它用于确定绑定值是在用户交互期间连续更新还是仅在 UI 元素放弃其响应者状态(即用户交互停止)时更新。这主要用于文本 field/view 绑定。
不幸的是,NSTableColumn
不能真正成为响应者,至少在传统意义上是这样。此选项对 NSTableColumn
的 width
.
令人困惑的是,此选项 也 对来自 NSSlider
的绑定没有影响。相反,如果 NSSlider
的 continuous
属性 是 false
,它将始终只更新鼠标向上的绑定,即使 .continuouslyUpdatesValue
选项在绑定上设置。相反,如果 NSSlider
的 continuous
属性 是 true
,它将始终不断更新绑定的值,即使 .continuouslyUpdatesValue
选项在绑定上设置为 false。
一些使用调试器的挖掘解释了这种行为。 NSSlider
始终更新其绑定值作为将其操作发送到其目标的副作用(无论 .continuouslyUpdatesValue
选项如何)。这解释了为什么它的 continuous
属性 完全决定了它的行为。
另一方面,当 NSTableColumn
更新其 width
属性 并因此在其宽度改变时连续发出 KVO 通知,它仅更新其 width
binding 作为发布它在宽度变化时发布的 columnDidResizeNotification
的副作用。此通知仅在调整大小结束时发布,而不是在调整大小期间发布。因此,NSTableColumn
只会在调整大小结束时更新其绑定。