Cocoa 绑定 - NSTableView - 交换值

Cocoa Bindings - NSTableView - Swapping Values

NSValueTransform 子class 是将 Core Data 属性显示到 UI 视图中的不错选择吗显示:

  1. 将数字字符串(0、1、2、3 等)转换为(待处理、已完成、已冻结、进行中等)等字符串
  2. 像 (0,1) 这样的数字字符串到基于应用程序的图像中(red.png if 0,green.png if 1)

这是 Core Data 显示的两个属性(计时器和状态)的内容:

这是我想要显示的内容,而不更改核心数据中的值:

如果不使用 NSValueTransformer,还有什么其他可能的方法?

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

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

是的,NSValueTransformer subclass可以很好地满足这个目的。

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

例如:

+ (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: 的文档以了解其工作原理。

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

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