4

我在努力嘗試執行我認爲會是相對常見的任務。我有一個NSTableView,它通過NSArrayController綁定到它的數組。陣列控制器將其內容設置爲NSMutableArray,其中包含一個或多個NSObject模型類的實例。我不知道該怎麼做的是以一種對綁定友好的方式在NSCell子類中公開模型。在NSTableView的自定義NSCell中使用綁定來暴露模型對象

爲了便於說明,我們會說對象模型是由名字,姓氏,年齡和性別組成的人。因此,模型會出現如下所示:

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

很明顯,適當的setter,getters init等等等級的類。

在我的控制器類我定義一個NSTableViewNSMutableArrayNSArrayController

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

使用界面生成器,我可以很容易地綁定模型到相應的列:

myPersonArray --> myPersonArrayController --> table column binding

該作品精細。所以我刪除了多餘的列,留下了一個與NSArrayController綁定的列(這會創建並保持每行與NSArrayController之間的關聯),這樣我就可以看到我的NSTableView中的一個可見列和一個隱藏列。我創建了一個NSCell子類,並將相應的繪製方法創建爲單元格。在我awakeFromNib我建立自定義NSCell子類:

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

這也能正常工作從圖形的角度。我得到我的自定義單元格顯示在列中,並重復我的數組控制器中的每個託管對象。如果我添加一個對象或從數組控制器中刪除一個對象,表格會相應地更新。

但是......我的印象是,我的PersonModel對象可以在我的NSCell子類中使用。但我不知道如何去實現它。我不想使用setter和getter來設置每個NSCell,因爲那麼我通過將數據存儲在NSCell而不是從陣列控制器中引用數據來打破整個模型概念。

是的,我確實需要有一個自定義NSCell,所以有多列不是一個選項。從哪裏來?

除了谷歌和StackOverflow搜索,我已經完成了蘋果公司文檔的必要步驟,似乎沒有找到答案。我發現很多參考文獻都是圍繞着布什打的,但沒有涉及NSArrayController。綁定到模型實體的其他元素(例如主/細節場景)時,控制器使生活變得非常簡單。我在使用核心數據時也發現了很多引用(雖然沒有答案),但是我沒有使用核心數據。

根據規範,我非常感謝任何可以提供的援助!

回答

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

的最後一步是引用該對象在NSCelldrawWithFrame,並根據需要按如下方式使用:

NSDictionary * thisCellObject = [self objectValue]; 

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

正如我希望的那樣,任何更新模型對象在自定義NSCell反映。

+0

這是輝煌的。我一直在與一個實施怪物一段時間掙扎,只有一個醜陋的弗蘭肯斯坦爲它展示。儘管我使用的是CoreData對象,但我認爲這是一個優雅的解決方案。 – 2010-05-13 16:45:56

+0

@Greg - 很高興我可以爲您服務!在我想出一個解決方案之前,我已經把頭繞在這個問題上了好幾天了! – Hooligancat 2010-05-27 15:56:47

0

我非常感謝這篇文章,Hooligancat,因爲我的項目在這個問題上停滯不前,而且儘管我看着Tim Isted的相同解決方案在http://www.timisted.net/blog/archive/custom-cells-and-core-data/ 我無法弄清楚。

只有當我讀了你的問題的優秀簡化和你的一分錢下降了解決方案的版本 - 我非常感謝!

+1

很高興我可以幫助。我真希望我能看到你發現的那個線索!大概會節省我幾個小時!所以我傾向於碰到比那些使用核心數據更牆我不我的應用程序使用的核心數據,因爲數據存儲在服務器端。無論哪種方式,我們都有工作解決方案! KEWL ... – Hooligancat 2010-06-08 19:50:53

1

還有一種不需要字典的方法。但是,它確實需要實施 - (ID)copyWithZone:你的數據類中(NSZone *)區的方法。例如:

- (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; } 

現在,在IB,你點的表列的在陣列控制器值 - > arrangedObjects

的drawWithFrame方法現在將從objectValue回報您的實際對象。

Activity *rowActivity = [self objectValue]; 

更改類需要更新所述copyWithZone方法,然後直接在drawWithFrame方法訪問數據。