如何根据复杂用户的选择显示绑定的NSManagedObject属性?

时间:2015-03-20 14:46:41

标签: macos core-data cocoa-bindings

在我的Core Data项目中,我集中使用了NArrayController和绑定,它的工作非常完美。有时我需要根据用户选择转换NSManagedObject's属性演示文稿(它在UI中的演示文稿)。

例如,我有实体'事件'它有一个属性'距离'用户可以选择如何显示它:米,公里,英里。对于这样简单的任务,我使用NSValueTransform

但是如何管理更复杂的场景呢?例如,我有实体'故障'它有一个属性' errorValue'。用户在UI中输入更正值,让我们将其命名为“faultCorrection'”。之后我需要显示“故障。错误值”'无处不在的故障.errorValue - faultCorrection'。

目前,基于具有静态属性的NSValueTransform,我有一些丑陋的解决方案。这些任务有什么好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

我已就此主题做了一些额外的研究,似乎这个问题没有完美的解决方案,你要么需要打破MVC模式,要么使用静态变量或使用userDefaults(正如stevesliva指出的那样)。我找到了另一个解决方案。如果在代码中完成绑定,则可能使用nsvaluetransform后代的特定实例。

变形金刚宣言:

@interface FaultCorrection : NSValueTransformer

-(void)setCorrection:(NSInteger)value;

@end

代码中的绑定使用以下变量:

  • self.tableView - NSTableView
  • self.ctrl - NSArrayController
  • self.transformer - FaultCorrection

-(void)bindIt {
   NSDictionary * opt = nil;

if ( self.transformer ) { opt = [ NSDictionary dictionaryWithObject:self.transformer forKey:NSValueTransformerBindingOption ]; }

[ self.tableView bind:NSContentBinding toObject:self.ctrl withKeyPath:@"arrangedObjects" options:nil ]; [ self.tableView.tableColumns[0] bind:NSValueBinding toObject:self.ctrl withKeyPath:@"arrangedObjects" options:opt ]; }

当用户更改faultCorrection时调用此方法:

-(void)update {
  [ self.transformer setCorrection: [self.fieldCorrection intValue]];
  [ self.tableView reloadData ];
}

答案 1 :(得分:0)

将视图绑定到实体的属性的值转换实际上可能是分离事物的最MVC方式。事实上,它可能是最好的方法,因为如果你可以实现反向变换,你会得到双向绑定。因此,简而言之,没有更好的解决方案。只是不同的。

但在您的情况下,我可能会在实体的支持类上实现另一个符合KVC标准的属性。像displayValue之类的东西,并绑定到那个。如果我在IB中查找绑定,我发现代码更容易理解,请参阅" displayValue"然后找到合适的方法。

问题是,听起来faultCorrection是应用程序或视图状态的一部分,而不是实例/实体状态,因此任何displayValue方法仍然需要在某处查询单例。你说目前这些是静态属性。使用符合绑定的[NSUserDefaultsController sharedUserDefaultsController]

可能更好

所以,所有这一切,在实体的类上都要这样绑定到:

- (NSString*) displayValue
{
    NSUserDefaultsController* defaults = NSUserDefaultsController.sharedUserDefaultsController;
    NSNumber* faultCorrection = [defaults valueForKeyPath:@"faultCorrection"];
    return [NSString stringWithFormat:@"%d",self.errorValue.floatValue - faultCorrection.floatValue];
}
+ (NSSet*) keyPathsForValuesAffectingDisplayValue 
{
    return [NSSet setWithObject:@"errorValue"];
}

如果用户更改了sharedUserDefaults中的faultCorrection值,您必须弄清楚如何重新触发displayValue绑定KVO。如何做到这一点取决于用户设置它的位置。而且你的valueTransformers目前使用的任何静态值都存在同样的问题 - 没有实例keyPathForValuesAffecting...方法可用于将静态值注册为依赖键路径。让每个实体实例KVO观察sharedUserDefaults可能有点过分,如果你可以将ViewController吹掉并重新启动它。

另外,除此之外,这与this recent question

所涵盖的主题非常相似