首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在设置绑定属性时观察到NSUserDefaultsController不工作

在设置绑定属性时观察到NSUserDefaultsController不工作
EN

Stack Overflow用户
提问于 2010-01-25 19:00:43
回答 3查看 1.5K关注 0票数 2

设置如下:我有一个IKImageBrowserView的子类,它的zoomValue属性被绑定到共享NSUserDefaultsController中的一个密钥VFBrowserZoomValue。我有一个NSSlider,它的value绑定绑定到同一个键。

这可以完美地从滑块更改浏览器的zoomValue

我正在尝试在我的IKImageBrowserView子类中实现-magnifyWithEvent:,以允许在触控板上使用收缩手势缩放浏览器。

下面是我的实现:

代码语言:javascript
复制
-(void)magnifyWithEvent:(NSEvent *)event
{
  if ([event magnification] > 0) {
    if ([self zoomValue] < 1) {
      [self setZoomValue: [self zoomValue] + [event magnification]];
    }
  } 
  else if ([event magnification] < 0) {
    if ([self zoomValue] + [event magnification] > 0.1) {
      [self setZoomValue: [self zoomValue] + [event magnification]];
    }
    else {
      [self setZoomValue: 0.1];
    }
  }
}

这会正确地更改浏览器的zoomValue。问题是NSUserDefaults没有用新值更新。

在应用程序的其他地方,我有一个观察浏览器zoomValue-observeValueForKeyPath:ofObject:change:context:实现。如果我在该方法中记录浏览器的缩放、滑块的值和键的默认值,我会看到浏览器的zoomValue没有被推入NSUserDefaults,滑块也没有更新。

我尝试用调用-{will,did}ChangeValueForKey来包围-magnifyWithEvent:方法,但是没有效果。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-01-26 06:13:00

绑定的KVO流不是正交的;绑定不是属性,它是对属性的引用。以下是要记住的绑定工作方式的简写:

  • KVO用于传达模型到控制器和视图的更改。
  • KVC用于传达视图到控制器和模型的更改。

因此,当具有绑定的视图处理事件时,它需要将更改传播到其绑定引用本身的属性。

下面是您的代码可能的样子,其中包含一个实用方法,用于完成通过绑定传播更改的繁重工作:

代码语言:javascript
复制
- (void)magnifyWithEvent:(NSEvent *)event
{
  if ([event magnification] > 0) {
    if ([self zoomValue] < 1) {
      [self setZoomValue: [self zoomValue] + [event magnification]];
    }
  } 
  else if ([event magnification] < 0) {
    if ([self zoomValue] + [event magnification] > 0.1) {
      [self setZoomValue: [self zoomValue] + [event magnification]];
    }
    else {
      [self setZoomValue: 0.1];
    }
  }

  // Update whatever is bound to our zoom value.
  [self updateValue:[NSNumber numberWithFloat:[self zoomValue]]
         forBinding:@"zoomValue"];
}

有点遗憾的是,ImageKit需要使用@"zoomValue"来引用IKImageBrowserView的Zoom值绑定,AppKit中的大多数绑定都有自己的全局字符串常量,比如NSContentBinding

下面是通过绑定传播更改的通用实用程序方法:

代码语言:javascript
复制
- (void)updateValue:(id)value forBinding:(NSString *)binding
{
  NSDictionary *bindingInfo = [self infoForBinding:binding];

  if (bindingInfo) {
    NSObject *object = [bindingInfo objectForKey:NSObservedObjectKey];
    NSString *keyPath = [bindingInfo objectForKey:NSObservedKeyPathKey];
    NSDictionary *options = [bindingInfo objectForKey:NSOptionsKey];

    // Use options to apply value transformer, placeholder, etc. to value
    id transformedValue = value; // exercise for the reader

    // Tell the model or controller object the new value
    [object setValue:transformedValue forKeyPath:keyPath];
  }
}

实际应用占位符、值转换器等留给读者作为练习。

票数 4
EN

Stack Overflow用户

发布于 2010-01-25 23:43:19

恐怕这是预期的行为,请参阅绑定文档的this FAQ section。您需要手动推送。

票数 0
EN

Stack Overflow用户

发布于 2010-01-26 00:06:26

当您创建一个兼容绑定的控件(或者,在您的例子中,是一个子类化)时,当它的值发生变化时,应由控件通知控制器。因此,您要做的是覆盖

代码语言:javascript
复制
- (void)bind:(NSString *)binding toObject:(id)observableController withKeyPath:(NSString *)keyPath options:(NSDictionary *)options

注意你感兴趣的绑定。跟踪observableControllerkeyPath (如果将使用任何值转换器,还要跟踪options字典)。当您更新控件的值时,您需要发送

代码语言:javascript
复制
[observableController setValue:newValue forKeyPath:keyPath];

使用新值更新控制器。键值观察是单行道,绑定中的控件是观察者。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2131750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档