NSOutlineView - 返回对象值,但只返回占位符标题" Table View Cell"被展示

时间:2014-10-12 22:03:25

标签: objective-c cocoa nsoutlineview

我正在编写一个暂时名为" CocoaMix"的小应用程序,其目的是测试我为访问各种UI上的辅助功能层次结构而编写的代码。基本上我想要完成的是左边的NSOutlineView和"示例"查看测试用户界面的右侧。

到目前为止,对于我的数据源实现:

@interface CMTopLevelCategory : NSObject

@property (readonly) NSString *name;

@property (readonly) NSArray *examples;

- (id)initWithName:(NSString *)name examples:(NSArray *)examples;

@end


@interface CMExample : NSObject

@property (readonly) NSString *name;

- (id)initWithName:(NSString *)name;

@end


@interface CMSideOutlineViewDataSource : NSObject <NSOutlineViewDataSource>

@end


//...


#define CMNameColumnIdentifier @"name"
#define CMCountColumnIdentifier @"count"

@interface CMSideOutlineViewDataSource ()

@property NSArray *topLevelCategories;

@end

@implementation CMSideOutlineViewDataSource

- (id)init {
    self = [super init];
    if (self) {
        CMExample *largeTableExample = [[CMExample alloc] initWithName:@"Large Table"];
        CMTopLevelCategory *tablesCategory = [[CMTopLevelCategory alloc] initWithName:@"Tables" examples:@[ largeTableExample ]];

        _topLevelCategories = @[ tablesCategory ];
    }
    return self;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    if (item) {
        if ([item isKindOfClass:CMTopLevelCategory.class]) {
            CMTopLevelCategory *topLevelCategory = item;
            return [topLevelCategory.examples objectAtIndex:index];
        }
    } else {
        return [self.topLevelCategories objectAtIndex:index];
    }
    return nil;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return [item isKindOfClass:CMTopLevelCategory.class];
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    if (item) {
        if ([item isKindOfClass:CMTopLevelCategory.class]) {
            CMTopLevelCategory *topLevelCategory = item;
            return [topLevelCategory.examples count];
        }
    } else {
        return [self.topLevelCategories count];
    }
    return 0;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    if ([item isKindOfClass:CMTopLevelCategory.class]) {
        CMTopLevelCategory *topLevelCategory = item;
        if ([tableColumn.identifier isEqualToString:CMNameColumnIdentifier]) {
            return topLevelCategory.name;
        } else if ([tableColumn.identifier isEqualToString:CMCountColumnIdentifier]) {
            return [NSNumber numberWithUnsignedInteger:[topLevelCategory.examples count]];
        }
    } else if ([item isKindOfClass:CMExample.class]) {
        CMExample *example = item;
        if ([tableColumn.identifier isEqualToString:CMNameColumnIdentifier]) {
            return example.name;
        }
    }
    return @"default value";
}

@end

为了解释这一点,顶级项目应该是&#34; Tables&#34;等示例的类别,然后对于每个类别,将会有一些示例UI(例如&#34; Large Table&# 34;在&#34;表&#34;示例类别中。)

当我构建并运行时,触发了outlineView:objectValueForTableColumn:byItem:中设置的断点,但NSOutlineView中的文本仍然是占位符&#34;表格单元格视图&#34;文本:

Screenshot of the "CocoaMix" application window

我做错了什么?

3 个答案:

答案 0 :(得分:4)

我将采取一些猜测。您可能正在使用基于视图的大纲视图。单元格视图可能是NSTableCellView个,每个都有NSTextField

大纲视图采用数据源从其-outlineView:objectValueForTableColumn:byItem:方法返回的对象值,如果它响应该方法,则在单元视图上调用-setObjectValue:NSTableCellView确实如此。

因此,现在您的表格单元格视图已设置objectValue。那是做什么的?可能没什么。

您可以使用绑定将子视图绑定到表格单元格视图,其中关键路径通过objectValue。因此,您可以将文本字段的Value绑定绑定到表格单元格视图,其关键路径为objectValue。这将导致文本字段显示值。

另一种方法是子类NSTableCellView并将该自定义子类用作大纲视图中的单元格视图。然后,覆盖-setObjectValue:,除了调用super之外,您还可以将对象值传递给子视图。要访问子视图,您可以将它们连接到textField的标准imageViewNSTableCellView出口,或者您可以向自定义子类添加更多出口,在IB中连接它们,然后使用它们。

我认为绑定方法最简单。此外,它提供了更大的灵活性。您对-outlineView:objectValueForTableColumn:byItem:的实施只能返回item。然后,文本字段的绑定可以使用objectValue.name作为模型关键路径。如果您添加更多子视图,他们可以使用不同的键路径来显示项目的不同方面。

对于不同的列,您将使用不同的单元视图子层次结构,其子视图的绑定将使用不同的键路径,但使用相同的objectValue。我们的想法是该行代表一个给定的项目,因此objectValue将是该项目,而列只会使用该项目中的不同属性。

另一种可能的方法是,如果您确定大纲视图在单元格视图中只有文本字段,则根本不使用NSTableCellView(或子类)。相反,使用裸NSTextField s作为您的单元格视图。在这种情况下,当大纲视图在单元格视图上调用-setObjectValue:时,它将是文本字段(响应该方法),并且将设置其值而不需要额外的步骤。

答案 1 :(得分:1)

将JSOZapps解释为here,将NSOutlineView的内容模式更改为基于单元格。

答案 2 :(得分:0)

参考@Ken 我附上截图。

  1. 选择您的 tableViewcell。
  2. 转到绑定检查器。
  3. 勾选“绑定到”到 tableCellView enter image description here