【问题标题】:Cocoa Bindings - NSTableView - Swapping ValuesCocoa 绑定 - NSTableView - 交换值
【发布时间】:2015-05-19 07:31:24
【问题描述】:

NSValueTransform 子类是在 UI 视图中显示 Core Data 属性的好选择吗:

  1. 像 (0,1,2,3,etc) 这样的数字字符串变成像 (Pending, Completed, Frozen, In progress, etc) 这样的字符串
  2. 像 (0,1) 这样的数字字符串到基于应用程序的图像中(red.png 如果 0,green.png 如果 1)

以下是 Core Data 显示的两个属性,计时器和状态:

这是我想要显示的内容,而不更改 Core Data 中的值:

如果不使用 NSValueTransformer,还有什么方法可以实现?

我不想看到永久转换的数据,只是为了减少存储在 Core Data 中的数据和更好的 UI 视图项。

我也尝试过修改托管对象类中的属性(没有 KVO 通知),但没有成功。

【问题讨论】:

  • 我不这么认为,对于 1 或 2。值转换器非常适合将对象填充到核心数据中,并且它们非常适合将字符串转换为字符串和数字等等。但是#1您将与实体中的状态属性相关联,并且没有理由不让模型显式,并让视图将其转换为可读的东西,而不是基本上将其埋在访问器附件中,这就是值转换在这里。当我使用它们时,我永远不会立即找到它们,埋在远离它们重要的地方。
  • 另外,在枚举类型的高效存储方面,还有this answer about enums in Core Data
  • 其实还不错……我刚刚在 NSTableView 中添加了一个 NSValueTransform,之前我只是在其中显示枚举的 int 值……而且效果很好!
  • @geowar 你实现了变换和反向变换吗?这些方法是在哪个类中编写的?我没有看到如何将字符串转换为图像,然后将图像转换回字符串。
  • 您不需要可逆变换。用户可以修改这些视图吗?这将如何运作?

标签: objective-c cocoa nstableview cocoa-bindings nsvaluetransformer


【解决方案1】:

是的,NSValueTransformer 子类可以很好地用于此目的。

您还可以将只读计算属性添加到托管对象类,这也应该有效。如果这些属性作为模型代码的一部分没有意义,甚至可以通过控制器代码中的类别添加。

例如:

+ (NSSet*) keyPathsForValuesAffectingStatusDisplayName
{
    return [NSSet setWithObject:@"status"];
}
- (NSString*) statusDisplayName
{
    NSString* status = self.status;
    if ([status isEqualToString:@"0"])
        return @"Pending";
    else if ([status isEqualToString:@"1"])
        return @"Completed";
    // ...
}

+keyPathsForValuesAffectingStatusDisplayName 方法让 KVO 和绑定知道当 status 发生变化时,这个新的 statusDisplayName 属性也会发生变化。请参阅+keyPathsForValuesAffectingValueForKey: 的文档以了解其工作原理。

【讨论】:

  • 然后我们将这个 ValueTranformer 类添加到这些单元格的绑定中?感谢您提供代码建议。我将学习新课程,只读,明天回复。
  • 你知道在显示其他内容的同时保持属性值不变的另一种技术吗?
  • 是的,您需要将值转换器添加到这些单元格的绑定中。可能有多种方法可以显示不同的内容,例如为单元格使用自定义视图类,或在-tableView:viewForTableColumn:row: 中设置单元格,或其他任何方式。
【解决方案2】:

我最终使用了最初似乎阻止在这些单元格中显示不同信息的东西,使用:

#pragma mark - Table View Delegate

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    /*  tableColumn = (string) @"AutomaticTableColumnIdentifier.0"
                row = (int)    0          */
    NSString *identifier = [tableColumn identifier];
    NSTableCellView *cellView = [tableView makeViewWithIdentifier:identifier owner:self];

    NSManagedObject *item = [self.itemArrayController.arrangedObjects objectAtIndex:row];

    if ([identifier isEqualToString:@"AutomaticTableColumnIdentifier.0"]) {
        /*  subviews returns array with  0 = Image View &
                                         1 = Text Field      */
        /*  First, set the correct timer image  */
        ...  logic  ...
        NSImageView *theImage = (NSImageView *)[[cellView subviews] objectAtIndex:0];
        theImage.image = [NSImage imageNamed:@"green.gif"];

        /*  Second, display the desired status  */
        NSTextField *theTextField = (NSTextField *)[[result subviews] objectAtIndex:1];
        ...  logic  ...
        theTextField.stringValue = @"Pending";
    }

    return cellView;
}

Apple 的文档(某处)指出,与数组控制器的绑定可以与手动填充表格视图单元格结合使用。从绑定开始,然后手动优化显示值似乎是最好和最简单的方法。

【讨论】:

    猜你喜欢
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多