代码之家  ›  专栏  ›  技术社区  ›  David Prem Acharya

Cocoa绑定-NSTableView-交换值

  •  1
  • David Prem Acharya  · 技术社区  · 11 年前

    NSValueTransform子类是在UI视图中显示核心数据属性的好选择吗

    1. 将(0,1,2,3等)等数字字符串转换为(Pending、Completed、Frozen、In progress等)等字符串
    2. 类似(0,1)的数字字符串转换为基于应用程序的图像(如果为0,则为red.png,如果为1,则为green.png)

    以下是核心数据显示的两个属性,计时器和状态:

    enter image description here

    以下是我希望在不更改核心数据中的值的情况下显示的内容:

    enter image description here

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

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

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

    2 回复  |  直到 11 年前
        1
  •  1
  •   Ken Thomases    11 年前

    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: 学习如何工作。

        2
  •  1
  •   David Prem Acharya    11 年前

    我最终使用了一种最初似乎阻止这些单元格中显示不同信息的方法,使用了:

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