设置如下:我有一个IKImageBrowserView的子类,它的zoomValue属性被绑定到共享NSUserDefaultsController中的一个密钥VFBrowserZoomValue。我有一个NSSlider,它的value绑定绑定到同一个键。
这可以完美地从滑块更改浏览器的zoomValue。
我正在尝试在我的IKImageBrowserView子类中实现-magnifyWithEvent:,以允许在触控板上使用收缩手势缩放浏览器。
下面是我的实现:
-(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:方法,但是没有效果。
发布于 2010-01-26 06:13:00
绑定的KVO流不是正交的;绑定不是属性,它是对属性的引用。以下是要记住的绑定工作方式的简写:
因此,当具有绑定的视图处理事件时,它需要将更改传播到其绑定引用本身的属性。
下面是您的代码可能的样子,其中包含一个实用方法,用于完成通过绑定传播更改的繁重工作:
- (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。
下面是通过绑定传播更改的通用实用程序方法:
- (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];
}
}实际应用占位符、值转换器等留给读者作为练习。
发布于 2010-01-25 23:43:19
恐怕这是预期的行为,请参阅绑定文档的this FAQ section。您需要手动推送。
发布于 2010-01-26 00:06:26
当您创建一个兼容绑定的控件(或者,在您的例子中,是一个子类化)时,当它的值发生变化时,应由控件通知控制器。因此,您要做的是覆盖
- (void)bind:(NSString *)binding toObject:(id)observableController withKeyPath:(NSString *)keyPath options:(NSDictionary *)options注意你感兴趣的绑定。跟踪observableController和keyPath (如果将使用任何值转换器,还要跟踪options字典)。当您更新控件的值时,您需要发送
[observableController setValue:newValue forKeyPath:keyPath];使用新值更新控制器。键值观察是单行道,绑定中的控件是观察者。
https://stackoverflow.com/questions/2131750
复制相似问题