我正在编写一个暂时名为" 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;文本:
我做错了什么?
答案 0 :(得分:4)
NSTableCellView
个,每个都有NSTextField
。
大纲视图采用数据源从其-outlineView:objectValueForTableColumn:byItem:
方法返回的对象值,如果它响应该方法,则在单元视图上调用-setObjectValue:
。 NSTableCellView
确实如此。
因此,现在您的表格单元格视图已设置objectValue
。那是做什么的?可能没什么。
您可以使用绑定将子视图绑定到表格单元格视图,其中关键路径通过objectValue
。因此,您可以将文本字段的Value绑定绑定到表格单元格视图,其关键路径为objectValue
。这将导致文本字段显示值。
另一种方法是子类NSTableCellView
并将该自定义子类用作大纲视图中的单元格视图。然后,覆盖-setObjectValue:
,除了调用super
之外,您还可以将对象值传递给子视图。要访问子视图,您可以将它们连接到textField
的标准imageView
和NSTableCellView
出口,或者您可以向自定义子类添加更多出口,在IB中连接它们,然后使用它们。
我认为绑定方法最简单。此外,它提供了更大的灵活性。您对-outlineView:objectValueForTableColumn:byItem:
的实施只能返回item
。然后,文本字段的绑定可以使用objectValue.name
作为模型关键路径。如果您添加更多子视图,他们可以使用不同的键路径来显示项目的不同方面。
对于不同的列,您将使用不同的单元视图子层次结构,其子视图的绑定将使用不同的键路径,但使用相同的objectValue
。我们的想法是该行代表一个给定的项目,因此objectValue
将是该项目,而列只会使用该项目中的不同属性。
另一种可能的方法是,如果您确定大纲视图在单元格视图中只有文本字段,则根本不使用NSTableCellView
(或子类)。相反,使用裸NSTextField
s作为您的单元格视图。在这种情况下,当大纲视图在单元格视图上调用-setObjectValue:
时,它将是文本字段(响应该方法),并且将设置其值而不需要额外的步骤。
答案 1 :(得分:1)
将JSOZapps解释为here,将NSOutlineView的内容模式更改为基于单元格。
答案 2 :(得分:0)