2012-06-29 63 views
17

對於可可,我有一個NSTableView設置爲基於查看。選擇一行時,文本字段將其顏色更改爲白色。我如何保持黑色?如何在行選擇上更改NSTextField文本顏色?

我還應該注意突出顯示設置爲來源列表(它在常規上做同樣的事情)。 Highlight Setting

未選行Unselected

所選行Selected Row

我希望類似的狀態配置於iOS的東西:

enter image description here

這個建議在2011年WWDC會議120但有點延遲,所以我不打算使用它。它可能適用於其他人。

- (void)tableViewSelectionDidChange:(NSNotification *)notification 
{ 
    [tableView enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row){ 
     NSTableCellView *cellView = [rowView viewAtColumn:0]; 
     if(rowView.selected){ 
      cellView.textField.font = [NSFont boldSystemFontOfSize:14]; 
     }else{ 
      cellView.textField.font = [NSFont systemFontOfSize:14]; 
     } 
    }]; 
} 
+0

這是否幫助? http://stackoverflow.com/questions/7949​​015/handling-custom-selection-style-in-view-based-nstableview – Augie

+0

謝謝。除非我錯過了一些東西,那更像是背景顏色。我已經爲我的自定義背景顏色做了一個。我正在尋找文字的顏色。 – joels

+0

當該行被取消選擇時,文本字段顏色是否變回?我試圖瞭解如何以及爲什麼會發生這種情況。 – paulmelnikow

回答

14

根據您爲什麼需要這樣做,有兩種方法。

您可以子類NSTableRowView並覆蓋-[NSTableRowView interiorBackgroundStyle]返回NSBackgroundStyleLight。這將告訴單元格他們在淺色背景上並繪製黑色文本,這將是黑色的。

另一種方法是子類NSTableCellView並覆蓋-[NSTableCellView setBackgroundStyle:]並在那裏設置顏色。

11

重寫NSTableCellView並添加此方法以更改選中單元格時的文本顏色。

- (void) setBackgroundStyle:(NSBackgroundStyle)backgroundStyle 
{ 
    NSTableRowView *row = (NSTableRowView*)self.superview; 
    if (row.isSelected) { 
     self.textField.textColor = [NSColor blackColor]; 
    } else { 
     self.textField.textColor = [NSColor whiteColor]; 
    } 

} 
+2

當有選擇時,這不會正確繪製,但窗口不是關鍵。可可(將於10.10)繪製灰色背景,但文本字段爲黑色,因此自定義控件需要繪製爲「不活動」。比較backgroundStyle!= NSBackgroundStyleLight以確定是否應將控件繪製爲活動似乎是關鍵。 – kainjow

10

不需要自定義代碼來完成該操作。

只需在Interface Builder中將標籤的顏色設置爲「標籤顏色」即可。只有當標籤具有「控制文本顏色」並且處於NSTableCellView中時,自動白/黑色纔會起作用。

0

根據@ sabes的回答,我創建了這個NSTextFieldCell子類,當您選擇或取消選擇某行時,您可以使用它來設置自定義文本顏色。您可以在IB中設置相關文本字段單元格的子類。

@interface SNBlueTextFieldCell : NSTextFieldCell 

@end 

@implementation SNBlueTextFieldCell 

- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle { 
    [self setTextColor:(backgroundStyle==NSBackgroundStyleDark ? [NSColor blackColor] : [NSColor blueColor])]; 
} 

@end 
1

我想出了一個不同的解決方案。如果Cocoa支持@IBOutletCollection,則繼承NSTableCellView將會很好。因爲那麼我可以有一個Cell子類,它有一個單元格中所有NSTextField的數組。但是由於我有許多種不同數量的NSTextField的單元格,我不喜歡這個選項。相反,我查看了NSTableCellView中backgroundStyle屬性的Apple文檔。

默認實現自動將調用轉發給實現setBackgroundStyle的所有子視圖:或者是NSControl,它們具有響應backgroundStyle的NSCell類。

如果我的TextFields實現setBackgroundStyle,那麼他們應該在單元格選擇更改時得到通知。但是,這種背景風格的轉發不是遞歸的。因爲我的NSTextFields在NSStackViews內,所以他們沒有收到消息。爲了解決這個問題,我只寫了一個擴展來實現所有NSView上的setBackgroundStyle。它只是轉發消息。最後,我爲NSTextField添加了一個擴展來實現此方法。從這個擴展名中,我改變文本顏色並調用超級。這個解決方案也很好,因爲不需要子類。沒有NSTableCellView或NSTextField的子類。

將此功能添加到所有視圖和所有NSTextFields可能會導致NSTextFields不在NSTableViews中時出現意外更改顏色的問題。但到目前爲止,只有我的TableViews/OutlineViews中的那些正在改變顏色,這就是我正在尋找的。如果您看到文本字段會改變您不期望的顏色,則可能需要對NSTextField進行子類化並僅在該子類上實現setBackgroundStyle覆蓋,而不是將其添加到所有NSTextField。

我使用的Swift 3中的代碼粘貼在下面。

extension NSView { 
    func setBackgroundStyle(_ newValue: NSBackgroundStyle) { 
     for view in self.subviews { 
      view.setBackgroundStyle(newValue) 
     } 
    } 
} 

extension NSTextField { 
    override func setBackgroundStyle(_ newValue: NSBackgroundStyle) { 
     switch newValue { 
     case .dark: 
      self.textColor = NSColor.controlLightHighlightColor 
     case .light, .lowered, .raised: 
      self.textColor = NSColor.labelColor 
     } 
     super.setBackgroundStyle(newValue) 
    } 
} 
1

對於我的Swift應用程序,上述任何一個都不能正常工作。此方法正確處理NSTableView失去焦點,並且當窗口不是關鍵窗口時,但單元格仍處於選中狀態。

NSTableCellView子類中使用以下命令:

override var backgroundStyle: NSView.BackgroundStyle { 
    willSet { 
    if newValue == .dark { 
     title.textColor = NSColor.white 
    } else { 
     title.textColor = NSColor.labelColor 
    } 
    } 
}