如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?
Posted
技术标签:
【中文标题】如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?【英文标题】:How to display bound NSManagedObject's property based on complex user's choice? 【发布时间】:2015-03-20 14:46:41 【问题描述】:在我使用Core Data
的项目中,我大量使用NArrayController
和绑定,它运行良好。有时我需要根据用户选择来转换 NSManagedObject's
属性表示(它是 UI 中的表示)。
例如,我有一个实体“事件”,它有一个属性“距离”。用户可以选择如何显示它:米、公里、英里。对于这样简单的任务,我使用NSValueTransform
。
但是如何管理更复杂的场景呢?例如,我有一个实体 'Fault',它有一个属性 'errorValue'。用户在 UI 中输入一个修正值,我们将其命名为“faultCorrection”。之后,我需要在任何地方将“Fault.errorValue”显示为“fault.errorValue - faultCorrection”。
目前,为此我有一些基于NSValueTransform
的丑陋解决方案,具有静态属性。此类任务有什么好的解决方案吗?
【问题讨论】:
【参考方案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 ];
【讨论】:
【参考方案2】:在将视图绑定到实体属性的位置进行值转换实际上可能是最 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所涵盖的主题非常相似
【讨论】:
感谢您的回答,看来这个任务没有完美的解决方案,我找到了另一个解决方案,并将其作为附加答案发布,也许对 smb 有帮助。以上是关于如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?的主要内容,如果未能解决你的问题,请参考以下文章
C#中 combox控件已绑定数据, 如何根据一个string类型字段 设置combox的选择项