9

我有两个窗口:窗口 A 从 NIB 加载;窗口 B 是通过编程方式创建的。

两个窗口都有一个 NStextView:窗口 A 中的 textview 的属性字符串使用 IBtext绑定到模型的属性;而窗口 B 中的 textview 的属性字符串使用方法绑定到模型的属性。text-[NSObject bind:toObject:withKeyPath:options:]

[textview bind:@"attributedString"
      toObject:obj
   withKeyPath:@"text"
       options:nil];

这是奇怪的事情:Window B 中的 textview 确实绑定到obj.text,但 textview 中的更改从未更新为obj.text. 但是,如果我在窗口 A 的 textview 中进行了更改,则obj.text窗口 B 中的和 textview 也会相应更新。

所以我在想,该-[NSObject bind:toObject:withKeyPath:options:]方法仅适用于单向绑定。我在 Cocoa 文档中找不到明确的解释。有没有人有这个问题的经验?如何在代码中实现双向绑定?

4

2 回答 2

5

Cocoa 绑定本质上是双向的,但某些行为(如文本字段的连续/实时更新)需要设置特定选项。在 IB 中,您需要确保选中“持续更新值”复选框。要以编程方式获得等效行为,您需要options在绑定上指定。这可能看起来像这样:

[textview bind: NSAttributedStringBinding 
      toObject: obj 
   withKeyPath: @"text" 
       options: (@{ 
                 NSContinuouslyUpdatesValueBindingOption : @YES })];

值得一提的是,在以编程方式设置绑定时,值得检查 IB 中的等效绑定并确保将所有相同的设置传递给编程绑定。例如,我在 IB 中看到“允许编辑多个值选择”、“有条件地设置可编辑”和“为不适用的键引发”选项默认情况下都会检查 NSTextView 的属性字符串绑定。这意味着我们的编程绑定应该看起来像:

[textview bind: NSAttributedStringBinding 
      toObject: obj 
   withKeyPath: @"text" 
       options: (@{ 
                 NSContinuouslyUpdatesValueBindingOption : @YES,
                 NSAllowsEditingMultipleValuesSelectionBindingOption : @YES,
                 NSConditionallySetsEditableBindingOption : @YES,
                 NSRaisesForNotApplicableKeysBindingOption : @YES })];
于 2013-02-14T02:20:04.960 回答
1

是的,bind: toObject: withKeyPath: options:是一种方法,没有任何选项可以影响这一点。这与您在 .nib 文件中进行绑定不同。像往常一样,Apple 忘记在其文档中提及如此简单的事情。这里最简单的解决方案是在创建正向绑定的同时创建反向绑定。当您分配值时,这不会死循环您的代码。这是用户默认值的示例:

// 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}];
于 2015-02-27T07:50:04.650 回答