18

对于可可,我有一个NSTableView设置为基于视图。选择一行后,文本字段的颜色将变为白色。如何保持黑色?

我还应该注意,突出显示设置为源列表(它在常规上做同样的事情)。 亮点设置

未选择的行未选中

选定行选定行

我希望有类似于 iOS 的状态配置的东西:

在此处输入图像描述

这是在 WWDC 2011 Session 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];
        }
    }];
}
4

7 回答 7

18

不需要自定义代码来实现这一点。

只需在 Interface Builder 中将标签的颜色设置为“标签颜色”即可。仅当标签设置了“控制文本颜色”并且位于 NSTableCellView 中时,自动白/黑功能才有效。

于 2015-04-16T11:57:01.037 回答
17

根据您需要这样做的原因,有两种方法。

您可以子类化NSTableRowView并覆盖-[NSTableRowView interiorBackgroundStyle]以返回NSBackgroundStyleLight。这将告诉单元格它们在浅色背景上并绘制黑色文本,这将是黑色的。

另一种方法是子类化NSTableCellView和覆盖-[NSTableCellView setBackgroundStyle:]并在那里自己设置颜色。

于 2012-08-17T14:52:38.863 回答
14

覆盖 NSTableCellView 并添加此方法以在选择单元格时更改文本颜色。

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

}
于 2014-02-11T19:23:29.050 回答
3

我想出了一个不同的解决方案。如果 Cocoa 支持 @IBOutletCollection,子类化 NSTableCellView 会很好。因为那时我可以有一个 Cell 子类,其中包含单元格中所有 NSTextFields 的数组。但由于我有多种类型的单元格和不同数量的 NSTextField,我不喜欢这个选项。相反,我查看了 Apple 为backgroundStyleNSTableCellView 中的属性提供的文档。

默认实现会自动将调用转发到所有实现 setBackgroundStyle: 或者是 NSControl 的子视图,这些子视图具有响应 backgroundStyle 的 NSCell 类。

如果我的 TextFields 实现了 setBackgroundStyle,那么它们应该在单元格选择发生变化时得到通知。但是,背景样式的这种转发不是递归的。因为我的 NSTextFields 在 NSStackViews 中,所以他们没有收到消息。为了解决这个问题,我刚刚编写了一个扩展来在所有 NSView 上实现 setBackgroundStyle。它只是转发消息。最后,我为 NSTextField 添加了一个扩展来实现这个方法。从这个扩展中,我改变了文本颜色并调用了 super。这个解决方案也很好,因为不需要子类。没有 NSTableCellView 或 NSTextField 的子类。

将此功能添加到所有视图和所有 NSTextFields 可能会导致不在 NSTableViews 中的 NSTextFields 出现意外更改颜色的问题。但到目前为止,只有我的 TableViews/OutlineViews 中的那些正在改变颜色,而这正是我正在寻找的。如果您看到文本字段更改了您不期望的颜色,您可能希望继承 NSTextField 并仅在该子类上实现 setBackgroundStyle 覆盖,而不是将其添加到所有 NSTextFields。

我使用的 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)
    }
}
于 2017-01-27T17:40:54.933 回答
2

对于我的 Swift 应用程序,上述方法似乎都不能正常工作。此方法正确处理 NSTableView 失去焦点以及当窗口不是关键窗口但仍选择单元格时。

NSTableCellView子类中使用以下内容:

override var backgroundStyle: NSView.BackgroundStyle {
  willSet {
    if newValue == .dark {
      title.textColor = NSColor.white
    } else {
      title.textColor = NSColor.labelColor
    }
  }
}
于 2017-09-27T11:57:10.023 回答
0

根据@sabes 的回答,我创建了这个NSTextFieldCell子类,您可以在选择或取消选择一行时使用它来设置自定义文本颜色。您可以在 IB 中设置相关文本字段单元格的子类。

@interface SNBlueTextFieldCell : NSTextFieldCell

@end

@implementation SNBlueTextFieldCell

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

@end
于 2015-07-01T16:48:56.863 回答
0

在 macOS 11 或更高版本中,不推荐使用.dark.light背景样式。但您可以.emphased改用:

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

在示例中,.labelColor是选定的颜色和.secondaryLabelColor未选定的颜色。

于 2021-02-18T12:17:11.043 回答