bind:toObject:withKeyPath:options: is one-way binding?

六月ゝ 毕业季﹏ 提交于 2019-12-01 03:48:19

Cocoa bindings are inherently two-way, but certain behaviors (like continuous/live updating of text fields) require specific options to be set. In IB you will want to make sure that the "Continuously Updates Value" check box is checked. To get equivalent behavior programmatically, you will need to specify options on the binding. That might look something like this:

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

It's worth mentioning that when setting up a binding programmatically, it's worth checking an equivalent binding in IB and making sure you're passing all the same settings to the programmatic binding. For instance, I see in IB that the "Allow Editing Multiple Values Selection", "Conditionally Sets Editable", and "Raises For Not Applicable Keys" options are all checked by default for an NSTextView's Attributed String binding. That would mean our programmatic binding should probably really look like:

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

Yes, bind: toObject: withKeyPath: options: is one way and no option can influence this. This is not the same as you make binding in .nib file. As usual Apple forgot to mention such simple thing in its docs. The simplest solution here is to create reverse binding at the same time when you create forward one. This will NOT dead loop your code when you assign the value. Here is the example with user defaults:

// 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}];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!