Cocoa - 在表视图中显示嵌套数组

时间:2011-11-28 15:26:04

标签: cocoa cocoa-bindings key-value-observing nsarraycontroller nstreecontroller

我有一个绑定到数组的树控制器,称为“内容”。 “content”是一个模型对象数组,称为“Car”。每个“Car”包含一个名为“carName”的NSString和一个名为“mostPopularColors”的NSMutableArray。 “mostPopularColors”包含NSMutableDictionary对象,其中的键包括:“最受欢迎”,“第二最受欢迎”,“第三最受欢迎”等等,以及“红色”,“绿色”,“蓝色”等值。

大纲视图绑定到树控制器排列的对象,并在“内容”中显示每个“Car”的“carName”。单独的表视图列出了一列中的每个“carName”。这是通过将一个数组控制器绑定到树控制器(控制器键:选择,模型键路径:allChildLeafs)来完成的。然后将表列值绑定到数组控制器的排列对象,模型键路径:carName。

在表格视图中,我想要另外两列分别列出最流行的颜色和第二种最流行的颜色。因此,决赛桌应该有三列,列出所有车名以及每辆车最常用的两种颜色。

我可以按照描述访问汽车名称,但不能访问颜色,因为它们本身就是数组。

我尝试制作第二个阵列控制器并将其链接到第一个但无法使其工作。

所以最后我希望能够在大纲视图中选择汽车或汽车,并在表格视图中查看它们的所有名称和前两种颜色。

1 个答案:

答案 0 :(得分:0)

似乎第二个阵列控制器无法工作,因为无法将两个阵列控制器连接到一个表视图。

绑定到树控制器的数组控制器(控制器键:选择,模型键路径:allChildLeafs)保留在原位但未绑定到任何视图。

在Xcode中创建了一个IBOutlet NSArrayController,然后连接到Interface Builder(IB)中新创建的数组控制器。此外,使用setter和getter方法声明了一个新的NSMutableArray。然后,使用以下代码将数组控制器绑定到新的NSMutableArray:

[newArrayController bind:NSContentArrayBinding toObject:self withKeyPath:@"mutableArray" options:nil];

所以现在数组控制器将“保持”新的可变数组中的任何内容。通过将新阵列控制器连接到表视图,可以在表视图中显示阵列的内容。

所需要的只是让这个可变数组包含每辆汽车的NSMutableDictionary对象。每个字典都有三个键值对。三个键是:“carName”,“mostPopularColor”,“secondMostPopularColor”。

由于旧的数组控制器保存了当前在大纲视图中选择的“Car”对象数组,因此首先获取该“Car”对象数组。为此,观察旧数组控制器的arrangeObjects中的更改,并使用以下方法观察新的“Car”对象数组:

[oldArrayController addObserver:self forKeyPath:@"arrangedObjects" options:NSKeyValueObservingOptionNew context:nil];

为了处理观察并使用新的“Car”对象数组来获取字典对象的最终数组,实现了以下方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context  {if (object == selectedChildLeafsController)
{
    if ([[object arrangedObjects] count] > 0)
    {//make a new mutable array, here called "array", of dictionaries from your array of "Car" objects which is found in [object arrangedObjects] . And then something like...
    [self setMutableArray: array];
    [newArrayController bind:NSContentArrayBinding toObject:self withKeyPath:@"selectedBonds" options:nil];}else
{
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}}