max*_*son 3 macos cocoa nsbrowser
我能够让我的 NSBrowser 实例在第一列中显示正确的数据。但是,当我选择其中一个选项时,下一列只会显示相同的一组选项。我已经阅读了文档,查看了 Apple 的所有相关示例代码,以及我在互联网上可以找到的几乎所有内容,但我根本无法找出实现所需方法的正确方法。我提供给浏览器的数据是一个字典数组。每个字典又包含一个“子”键,它是另一个字典数组。这些字典有自己的“子”键,它们也是字典数组等。使用 JSON 进行描述(对象是字典,数组是数组),它看起来像这样:
data = [
{
name: 'David',
children:[
{
name: 'Sarah',
children: {...}
},
{
name: 'Kevin',
children: {...}
}
]
},
{
name: 'Mary',
children:[
{
name: 'Greg',
children: {...}
},
{
name: 'Jane',
children: {...}
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
所以第一列应该显示“大卫”和“玛丽”。如果选择了“David”,下一列应显示“Sarah”和“Kevin”,依此类推。
我当前的实现依赖于我创建的自定义方法,该方法应该将浏览器的索引路径从提供的数据转换为相应的 NSArray 级别。这个方法看起来像:
- (NSArray *)getSelectionInBrowser:(NSBrowser *)browser
{
NSArray *selection = browserData;
NSIndexPath *path = [browser selectionIndexPath];
for (NSUInteger i = 0; i < path.length; i++) {
selection = [[selection objectAtIndex:i] objectForKey:@"children"];
}
return selection;
}
Run Code Online (Sandbox Code Playgroud)
我对所需的 NSBrowserDelegate 协议方法的实现如下所示:
- (NSInteger)browser:(NSBrowser *)sender numberOfRowsInColumn:(NSInteger)column
{
return [[self getSelectionInBrowser:sender] count];
}
- (NSInteger)browser:(NSBrowser *)browser numberOfChildrenOfItem:(id)item {
return [[self getSelectionInBrowser:browser] count];
}
- (id)browser:(NSBrowser *)browser child:(NSInteger)index ofItem:(id)item {
return [self getSelectionInBrowser:browser];
}
- (BOOL)browser:(NSBrowser *)browser isLeafItem:(id)item {
return ![item isKindOfClass:[NSMutableArray class]];
}
- (id)browser:(NSBrowser *)browser objectValueForItem:(id)item {
return nil;
}
- (void)browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(NSInteger)row column:(NSInteger)column {
NSArray *selection = [self getSelectionInBrowser:browser];
cell.title = [[selection objectAtIndex:row] objectForKey:@"name"];
}
Run Code Online (Sandbox Code Playgroud)
NSBrowser 的第一列填充了正确的名称。但是,一旦我做出选择,程序就会因错误而崩溃-[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 0]。进行一些调试后,它崩溃的代码行是objectAtIndex:我的自定义getSelectionInBrowser:.
这并不令我感到惊讶,因为即使在崩溃之前,我也认为依赖该自定义方法来检索当前选择是做错了什么。我想这项工作应该在委托方法本身中完成,并且当正确实现时,当前选择应该可以item在许多这些方法中提供的变量中访问。但是,我无法让它发挥作用。该item变量似乎始终只是根数据对象,而不是反映最“深入”的选择。
那么我该如何纠正我的实现呢?
解决了!这是我的最终工作代码。不需要那个自定义getSelection...方法,而且我拥有的一些委托方法是不必要的(只有使用过的你不会使用“基于项目的 API”)。
- (NSInteger)browser:(NSBrowser *)browser numberOfChildrenOfItem:(id)item {
if (item) {
return [[item objectForKey:@"children"] count];
}
return [browserData count];
}
- (id)browser:(NSBrowser *)browser child:(NSInteger)index ofItem:(id)item {
if (item) {
return [[item objectForKey:@"children"] objectAtIndex:index];
}
return [browserData objectAtIndex:index];
}
- (BOOL)browser:(NSBrowser *)browser isLeafItem:(id)item {
return [item objectForKey:@"children"] == nil;
}
- (id)browser:(NSBrowser *)browser objectValueForItem:(id)item {
return [item objectForKey:@"name"];
}
Run Code Online (Sandbox Code Playgroud)
第一种方法是如何告诉 NSBrowser 应该有的行数。第二种方法是确定应在给定行(索引)中表示哪些数据。在这两种情况下,您必须首先检查是否item确实存在。如果不是,那是因为您位于数据的根部(NSBrowser 中的第一列)。只有当 NSBrowser 中的一行(或项目!)被选中时,item变量才会保存任何内容。最后一个方法应该返回您希望在给定行中显示的字符串。
希望这对未来的人们有所帮助。
| 归档时间: |
|
| 查看次数: |
1101 次 |
| 最近记录: |