如何反转所选 NSTableView 行的文本颜色

How to invert text colour of selected NSTableView row

我有一个 NSTableView,我正在其中更改特定列中文本的颜色,但是当 selected 行时,文本不会更改为更合适的颜色,因此它可读。

Finder 的修改日期、大小和种类列有灰色文本,当您 select 行 file/folder 时,灰色文本变为白色(以便在蓝色突出显示内可读) .

我在 XCode 上找不到默认启用此行为的魔术复选框,所以有人知道我如何实现相同的效果吗?

我在 XCode 6.3 中使用 Swift。

谢谢。

您没有说您的单元格使用的是什么视图或视图层次结构。您也没有具体说明如何或在何处设置文本字段的颜色或什么颜色。

选择一行后,该行会自动计算其 interiorBackgroundStyle。如果它响应 -setBackgroundStyle: 或者是一个 NSControl 的单元格响应它,它还会设置单元格视图的 backgroundStyle

如果您的单元格视图是 NSTableCellView 的实例,它会将背景样式转发给满足相同条件的所有子视图。如果您使用不同的容器视图作为您的单元格视图,并且您希望像这样转发背景样式,则您必须在您的视图中自己实现它 class.

NSTextField 的单元格(NSTextFieldCell)响应 -setBackgroundStyle:,因此其背景样式由上述机制自动设置。如果 textColor 是标准控件颜色之一(例如 NSColor.controlTextColor()),文本字段单元格将自动将其文本颜色更改为白色,但如果您指定非标准颜色,则不会这样做。因此,如果您要为文本设置特定颜色,则您有责任在背景样式更改时更改它。

您可以使用 NSTableCellView 的子 class 并为 backgroundStyle 属性 添加 属性 观察者 (didSet)。这可以根据设置的样式更改文本字段的 textColor。例如,如果背景样式不是 .Dark,则可以使用自定义颜色;如果背景样式是 .Dark,则可以使用普通文本字段颜色 NSColor.controlTextColor()(以便文本字段实际显示它为白色)。

您也可以在文本字段中使用 NSTextFieldCell 的子class,并做同样的事情。或者覆盖 drawInteriorWithFrame(_:inView:) 以根据背景样式使用不同的文本颜色绘制。

在 Ken 的回复(上图)的帮助下,我能够让它工作。这是我想要的草稿:

import Cocoa

class CustomTextFieldCell: NSTextFieldCell {

    // When the background changes (as a result of selection/deselection) switch appropriate colours
    override var backgroundStyle: NSBackgroundStyle {
        didSet {
            if (backgroundStyle == NSBackgroundStyle.Dark) {
                if self.textColor == NSColor.redColor() {
                    self.textColor = NSColor.yellowColor()
                }
            } else if (backgroundStyle == NSBackgroundStyle.Light) {
                if (self.textColor == NSColor.yellowColor()) {
                    self.textColor = NSColor.redColor()
                }
            }
        }
    }

    // When the colour changes, switch to a better alternative for the cell's current background
    override var textColor: NSColor? {
        didSet {
            if let colour = self.textColor {
                if backgroundStyle == NSBackgroundStyle.Dark {
                    if self.textColor == NSColor.redColor() {
                        self.textColor = NSColor.yellowColor()
                    }
                } else if backgroundStyle == NSBackgroundStyle.Light {
                    if (self.textColor == NSColor.yellowColor()) {
                        self.textColor = NSColor.redColor()
                    }
                }
            }
        }
    }

}

如果我在身份检查器中将我的 CustomTextFieldCell 设置为我的 table 视图单元格的自定义 class,它就可以工作。我还需要为 textColor 添加一个 属性 观察器,以便当前突出显示的行得到相同的处理。我现在可能会更改它,以便它不是硬编码的,但这演示了这个概念。

谢谢肯。

如果您使用 NSColor.labelColor 等系统颜色,所选单元格的文本颜色会自动反转。如果您想为未选择的文本使用另一种颜色,您可以在自定义 NSTableCellView class:

中使用这样的代码
override var backgroundStyle: NSView.BackgroundStyle {
    willSet {
        textField.textColor = newValue == .emphasized ? .labelColor : .secondaryLabelColor
    }
}

在这个Swift例子中,选择的文字颜色是.labelColor,否则是.secondaryLabelColor