2012-01-12 113 views
1

使用自定義單元格填充NSTableView的最佳方式是什麼?NSTableView中的自定義單元格

當我填充標準數據時,我總是使用Cocoa綁定,並且在使用自定義單元格填充表格時總是使用數據源。我想知道的是,如果有一種方法可以將這兩個概念混合在一起進行優化設計。

使用Xcode 3(因此,IBPlugins)可悲的是不是一個選項。

+0

請按照下面的回答,並使其正確。如果真的有幫助 – 2014-01-12 07:16:03

回答

3

我個人不會mix綁定的數據和數據源。我沒有遇到任何事情,但試圖做到這一點。我確實有幾種方法可以幫助你。

有一件事我已經能夠做的是設置在IB自定義單元格類是IB知道的細胞之一的,然後覆蓋你需要什麼,以便讓它做什麼你要。但首先是一些背景和一些錯過的嘗試:

當綁定基於單元格的NSTableViews時,通常將綁定設置在列本身而不是列中的單元格。如果您在表列中使用自定義NSCell子類,那麼您會注意到,像列value這樣的綁定不再可用於該列,與單元格爲NSTextFieldCell時不同。我嘗試通過將value綁定設置爲NSTextFieldCell,然後切換出單元格 - 綁定仍然出現在綁定檢查器中,但它總是在運行時崩潰,並出現此錯誤:[<NSTableColumn 0x10252e910> valueForUndefinedKey:]: this class is not key value coding-compliant for the key value.

這使我瞭解了IB知道如何綁定的一個單元的子類化方法。我創建了NSTextFieldCell的一個子類,鑽取到Table Column中的「Text Field Cell - Text Cell」,然後在Identity Inspector中設置我的自定義子類。我能夠確認綁定仍然有效,IB仍將它視爲NSTextFieldCell。從那裏,我可以重寫我想要的自定義單元類中的任何方法並獲取自定義行爲。我沒有理由相信你不能用圖像單元來做到這一點。當然,這是一種虛假的方法,但取決於定製單元的「定製」,它可能會打敗一些自定義代碼來連接數據源。

我在進一步的實驗中發現,這是一個「IB問題」,而不是真正的NSTableView /綁定問題。還有一個很好的解決方法。

假設您想使用自定義單元格,並且想要將其綁定到某個任意模型對象。你將NSTableColumn Value綁定綁定到一個NSArrayController,該NSArrayController出售自定義模型對象的列表,每個自定義模型對象都有一個屬性,稱之爲dataForCustomCell,該對象返回自定義單元格需要做的事情。您可以設置TextFieldCell列(如IB中的默認值),然後將NSTableColumn的value綁定綁定到陣列控制器>arrangedObjects,然後輸入模型密鑰路徑dataForCustomCell。此時,假設dataForCustomCell返回的對象實現了NSCopying(如果它不會導致應用程序崩潰,但這與第二秒無關),如果您運行應用程序,您將看到的是NSTextFieldCell將在屏幕上調用- (NSString*)description對象返回dataForCustomCell並將該文本放入單元格中。

現在最有趣的部分:在你所屬對象(的NSView,NSViewController,等等等等)-awakeFromNib時間,更換DATACELL(和headerCell如果你喜歡),像這樣:

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 
    // Assuming you've got your NSTableView plugged into an IBOutlet property called table 
    NSTableColumn* col = [[self.table tableColumns] objectAtIndex:0]; 
    col.dataCell = [[[MYCustomCell alloc] init] autorelease]; 
} 

由於綁定位於NSTableColumn而不是單元本身,您可以換出單元而不必擔心重新綁定任何綁定。在您的自定義單元類中,覆蓋-(void)setObjectValue:,並且您將在運行時從綁定機制接收到一個調用,將對應於當前繪製的表格行的模型對象中dataForCustomCell屬性的對象推入。 (你也會得到一個呼叫在每個單元傳遞零,但似乎可以安全地忽略它,或者只是將它傳遞給超級。)

這種方法的一個缺點是,你只能得到一個「值」綁定NSTextFieldCell。解決方法是將Value綁定綁定到模型中更大/更高的「粒子」,然後在需要時在您的0123,實現中展開多個值。

這不是完美的,但它是'代碼行'修復,而不是'代碼行'的修復。

或者,假設您定位的是相當新近的MacOS版本,您也可以使用基於視圖的NSTableViews。它們相當不錯,並且以比基於NSCell的表格更合理的方式處理綁定。雖然這是一種完全不同的做事方式,所以很難說出你的任務將如何映射到它。有一個great video on the Apple developer site,可以讓您瞭解基於NSView的NSTableView。

+0

優秀的答案,謝謝你分享你的經驗。 – 2012-07-04 01:11:37

+0

精湛的解釋! – 2014-08-04 12:23:28