2012-06-29 64 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 
    } 
    } 
}