【问题标题】:How to invert text colour of selected NSTableView row如何反转所选 NSTableView 行的文本颜色
【发布时间】:2015-07-03 18:00:50
【问题描述】:

I have an NSTableView in which I'm changing the colour of the text in a particular column, but when a row is selected, the text does not change to a more appropriate colour so that it's readable.

Finder 的 Date Modified、Size 和 Kind 列有灰色文本,当您选择文件/文件夹行时,灰色文本会变为白色(以便在蓝色突出显示中可读)。

我在 XCode 上找不到一个神奇的复选框来默认启用此行为,那么有人知道我如何实现相同的效果吗?

我在 XCode 6.3 中使用 Swift。

谢谢。

【问题讨论】:

    标签: xcode cocoa nstableview


    【解决方案1】:

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

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

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

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

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

    您也可以为您的文本字段使用NSTextFieldCell 的子类并执行相同的操作。或者覆盖 drawInteriorWithFrame(_:inView:) 以根据背景样式使用不同的文本颜色进行绘制。

    【讨论】:

    • 在 tableView:viewForTableColumn:row: 委托方法中,我这样做是为了在基于视图的单元格中设置文本字段的颜色: cell.textField!.textColor = NSColor.redColor() .设置为 blackColor() 的单元格可以很好地反转,但 redColor() 不会。您的答案需要一些时间才能弄清楚,所以感谢您给我一些想法来研究。
    • 老兄,我会检查的,但如果这有效,你就是我的救星!!来自 UIKit 的 AppKit 太奇怪了 :)
    【解决方案2】:

    在 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 设置为我的表格视图单元格的自定义类,它就可以工作。我还需要为 textColor 添加一个属性观察器,以便当前突出显示的行得到相同的处理。我现在可能会对其进行更改,使其不会被硬编码,但这展示了这个概念。

    谢谢肯。

    【讨论】:

      【解决方案3】:

      如果您使用像NSColor.labelColor 这样的系统颜色,则所选单元格的文本颜色反转将自动发生。如果你想为未选中的文本使用另一种颜色,你可以在你的自定义 NSTableCellView 类中使用这样的代码:

      override var backgroundStyle: NSView.BackgroundStyle {
          willSet {
              textField.textColor = newValue == .emphasized ? .labelColor : .secondaryLabelColor
          }
      }
      

      在这个 Swift 示例中,选定的文本颜色为.labelColor,否则为.secondaryLabelColor

      【讨论】:

        猜你喜欢
        • 2011-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-24
        相关资源
        最近更新 更多