我有两个窗口:窗口A是从NIB加载的;和Window B以编程方式创建。
两个窗口都有一个NStextView:窗口A中textview的attributionString绑定到模型的属性text
使用IB ;而使用text
方法将Window B中textview的attributesString绑定到模型的-[NSObject bind:toObject:withKeyPath:options:]
属性。
[textview bind:@"attributedString"
toObject:obj
withKeyPath:@"text"
options:nil];
这是奇怪的事情:Window B中的textview确实绑定到obj.text
,但textview中的更改永远不会更新为obj.text
。但是,如果我在窗口A的文本视图中进行了更改,则obj.text
和窗口B中的textview会相应更新。
所以我在想,-[NSObject bind:toObject:withKeyPath:options:]
方法仅适用于单向绑定。我在Cocoa文件中找不到明确的解释。有没有人遇到过这个问题?如何在代码中实现双向绑定?
答案 0 :(得分:4)
Cocoa绑定本质上是双向的,但某些行为(如文本字段的连续/实时更新)需要设置特定选项。在IB中,您需要确保选中“连续更新值”复选框。要以编程方式获得等效行为,您需要在绑定上指定options
。这可能看起来像这样:
[textview bind: NSAttributedStringBinding
toObject: obj
withKeyPath: @"text"
options: (@{
NSContinuouslyUpdatesValueBindingOption : @YES })];
值得一提的是,在以编程方式设置绑定时,值得检查IB中的等效绑定并确保将所有相同的设置传递给程序绑定。例如,我在IB中看到,默认情况下,对于NSTextView的Attributed String绑定,都会选中“允许编辑多个值选择”,“有条件地设置可编辑”和“引发不适用键”选项。这意味着我们的程序化绑定应该真的看起来像:
[textview bind: NSAttributedStringBinding
toObject: obj
withKeyPath: @"text"
options: (@{
NSContinuouslyUpdatesValueBindingOption : @YES,
NSAllowsEditingMultipleValuesSelectionBindingOption : @YES,
NSConditionallySetsEditableBindingOption : @YES,
NSRaisesForNotApplicableKeysBindingOption : @YES })];
答案 1 :(得分:1)
是的, bind:toObject:withKeyPath:options:是一种方式,没有任何选项可以影响这一点。这与您在.nib文件中进行绑定不同。像往常一样,苹果忘记在其文档中提到这么简单的事情。这里最简单的解决方案是在创建前向绑定的同时创建反向绑定。 分配值时,这不会使代码死循环。 以下是用户默认值的示例:
// two way binding of MyObject.myValue to user defaults
[NSUserDefaultsController.sharedUserDefaultsController.values bind: @"myValueInDefaults"
toObject: myObject
withKeyPath: @"myValue"
options: @{@"NSContinuouslyUpdatesValue":@YES}];
[myObject bind: @"myValue"
toObject: NSUserDefaultsController.sharedUserDefaultsController
withKeyPath: @"values.myValueInDefaults"
options: @{@"NSContinuouslyUpdatesValue":@YES}];