4

我正在努力尝试执行我认为相对常见的任务。我有一个NSTableView通过NSArrayController. 数组控制器将其内容设置为NSMutableArray包含一个或多个NSObject模型类实例的 。我不知道该怎么做NSCell是以绑定友好的方式在子类中公开模型。

为了说明的目的,我们将说对象模型是一个由名字、姓氏、年龄和性别组成的人。因此,模型将如下所示:

@interface PersonModel : NSObject {
    NSString * firstName;
    NSString * lastName;
    NSString * gender;
    int * age;
}

显然,适合该类的 setter、getter init 等。

在我的控制器类中,我定义了一个NSTableViewNSMutableArray和一个NSArrayController

@interface ControllerClass : NSObject {
    IBOutlet NSTableView * myTableView;
    NSMutableArray * myPersonArray;
    IBOutlet NSArrayController * myPersonArrayController;
}

使用 Interface Builder,我可以轻松地将模型绑定到适当的列:

myPersonArray --> myPersonArrayController --> table column binding

这工作正常。所以我删除了额外的列,留下一个隐藏的绑定到的列NSArrayController(这会创建并保持每一行和 之间的关联NSArrayController),这样我就可以在我的NSTableView和一个隐藏的列中找到一个可见的列。我创建一个NSCell子类并放置适当的绘图方法来创建单元格。在我的awakeFromNib我建立自定义NSCell子类:

MyCustomCell * aCustomCell = [[[MyCustomCell alloc] init] autorelease];
[[myTableView tableColumnWithIdentifier:@"customCellColumn"] 
     setDataCell:aCustomCell];

从绘图的角度来看,这也可以正常工作。我让我的自定义单元格显示在列中,并且它对我的数组控制器中的每个托管对象重复。如果我从数组控制器中添加对象或删除对象,则表会相应更新。

但是......我的印象是我的PersonModel对象可以从我的NSCell子类中获得。但我不知道怎么去。我不想NSCell使用 setter 和 getter 来设置每个,因为那样我通过将数据存储在NSCell而不是从数组控制器中引用它来打破整个模型概念。

是的,我确实需要自定义NSCell,因此不能选择多列。从这里到哪里?

除了 Google 和 StackOverflow 搜索之外,我还对 Apple 的文档进行了强制浏览,但似乎没有找到答案。我发现了很多绕圈子但没有涉及到NSArrayController. 当绑定到模型实体的其他元素(例如主/细节场景)时,控制器使生活变得非常容易。我在使用 Core Data 时也发现了很多参考资料(虽然没有答案),但我没有使用 Core Data。

按照惯例,我非常感谢可以提供的任何帮助!

4

3 回答 3

3

终于想通了这个。做了一些事情的人。所以这就是我需要做的......

首先,我需要在我的模型对象中创建一个模型键值数组,并NSDictionary从模型中返回这些键值。

因此我的模型有两种新方法如下(基于我上面的简化示例):

+(NSArray *)personKeys
{
    static NSArray * personKeys = nil;
    if (personKeys == nil)
        personKeys = [[NSArray alloc] initWithObjects:@"firstName", @"lastName", @"gender", @"age", nil];

    return personKeys;
}

-(NSDictionary *)personDictionary
{
    return [self dictionaryWithValuesForKeys:[[self class] personKeys]];
}

实施后,我将value表中的界限分配给

arrayController --> arrangeObjects --> personDictionary.

最后一步是根据需要引用NSCell drawWithFrame和使用中的对象,如下:

NSDictionary * thisCellObject = [self objectValue];

NSString * objectFirstName = [thisCellObject valueForkey:@"firstName"];
NSString * objectLastName = [thisCellObject valueForKey:@"lastName"];

正如我所希望的,对模型对象的任何更新都会反映在 custom 中NSCell

于 2010-04-20T23:25:33.823 回答
1

There is another approach that does not require the dictionary. However, it does require the implementation of the - (id)copyWithZone:(NSZone *)zone method within your data class. For example:

- (id)copyWithZone:(NSZone *)zone {
    Activity *copy = [[self class] allocWithZone: zone];
    copy.activityDate = self.activityDate;
    copy.sport = self.sport;
    copy.sportIcon = self.sportIcon;
    copy.laps = self.laps;
    return copy; }

Now in IB, you point the Table Column's value at Array Controller --> arrangedObjects

The drawWithFrame method will now return your actual object from the objectValue.

Activity *rowActivity = [self objectValue];

Changing the class requires updating the copyWithZone method and then accessing the data directly in your drawWithFrame method.

于 2012-02-14T18:12:09.630 回答
0

我非常感谢这篇文章,Hooligancat,因为我的项目在这个问题上停滞不前,并且尽我所能在http://www.timisted.net/blog/archive/custom-cells-上查看 Tim Isted 的相同解决方案and-core-data/ 我想不通。

只有当我读到您对问题的出色简化和您的解决方案版本时,一分钱都掉了——我非常感激!

于 2010-06-01T13:44:14.737 回答