具有自定义文本颜色和正确编辑文本颜色的 NSTableView(基于视图)

NSTableView (view based) with custom text colors and correct editing text color

更改基于 NSTableView 的视图中的文本颜色可以通过使用自定义 table 单元格视图并实现 setBackgroundStyle:

来完成
- (void)setBackgroundStyle: (NSBackgroundStyle)backgroundStyle {
  [super setBackgroundStyle: backgroundStyle];

  UICoverageElement *element = self.objectValue;

  if (backgroundStyle == NSBackgroundStyleEmphasized) {
    self.textField.textColor = NSColor.highlightColor;
  } else {
    if ([element.value isEqualToString: @"<no name>"]) {
      self.textField.textColor = NSColor.tertiaryLabelColor;
    } else if ([element.value hasPrefix: @"UI"]) {
      self.textField.textColor = typeColor;
    } else if ([element.value hasPrefix: @"["] || [element.value hasPrefix: @"{"]) {
      self.textField.textColor = objectColor;
    } else {
      self.textField.textColor = NSColor.textColor;
    }
  }
}

这很好用:

但在编辑单元格时会出现问题。在这种情况下,字段编辑器显然采用当前手动设置的文本颜色(选定行为白色)并在具有白色背景的字段编辑器中显示:

现在的问题是:如何在编辑单元格视图时设置正确的文本颜色?

setBackgroundStyle 在编辑开始时没有被调用,这使得无法在此函数中修复该问题。我尝试了各种指示编辑过程开始的方法,但调用了 none(但是 are 调用了独立的文本字段)。当我没有设置 highlightColor 时,编辑器颜色是正确的,但所选行的高亮颜色是错误的。

我之前回答过一个相关问题。不确定是否应将其标记为重复:

要点是文本​​编辑模式由一个名为 field editor 的单独对象处理。您应该创建一个新实例,并使用它来自定义 table.

编辑过程中的外观

windowWillReturnFieldEditor NSWindow 的委托方法询问使用哪个编辑器来编辑 client。当代表要求为您的 table.

创建一个编辑器时,您为您的 table 和 return 创建一次这样的编辑器
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client {

    if (/* client is a textfield or subview in your table */) {
        // Create customEditor elsewhere once
        // Get row number or data that corresponds to client view
        // Cusomize customEditor colors accordingly
        return customEditor;
    }

    return nil; // Use default editor
}

老实说,这是您认为非常简单明了的事情之一,但不幸的是,事实并非如此。

在字段编辑器中影响颜色的唯一方法是:

a) 在调用 NSCell 的 selectWithFrame:... 方法之前,将文本字段的颜色设置为所需的颜色 b) 更改在调用 selectWithFrame:... 后放置到字段编辑器中的文本的颜色。

一般来说:

a) 子类 NSTextFieldCell 并将字段的文本颜色设置回通常的默认值,然后 设置字段编辑器。

- (void)selectWithFrame:(NSRect)rect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)delegate start:(NSInteger)selStart length:(NSInteger)selLength
{
    self.textColorWhenNotEditing = self.textColor;
    self.textColor = NSColor.controlTextColor;
    [super selectWithFrame:rect inView:controlView editor:textObj delegate:delegate start:selStart length:selLength];
}

- (void)endEditing:(NSText *)textObj
{
    [super endEditing:textObj];
    self.textColor = self.textColorWhenNotEditing;
}

b) 直接更改字段编辑器

- (void)selectWithFrame:(NSRect)rect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)delegate start:(NSInteger)selStart length:(NSInteger)selLength
{
    [super selectWithFrame:rect inView:controlView editor:textObj delegate:delegate start:selStart length:selLength];

    NSMutableDictionary * attribs = [((NSTextView *)textObj).typingAttributes mutableCopy];
    attribs[NSForegroundColorAttributeName] = NSColor.controlTextColor;

    [((NSTextView *)textObj).textStorage setAttributes:attribs range:NSMakeRange(0, textObj.string.length)];
    ((NSTextView *)textObj).typingAttributes = attribs;
}