简体   繁体   中英

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

Changing the text color in a view based NSTableView can be accomplished by using a custom table cell view and implement 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;
    }
  }
}

This works nice and well:

在此处输入图片说明

but causes trouble when editing a cell. In this case the field editor obviously takes the current manually set text color (which is white for a selected row) and shows that in a field editor with white background:

在此处输入图片说明

Now the question is: how can I set the correct text color when a cell view is being edited?

setBackgroundStyle is not called when editing starts, which makes it impossible to fix that problem in this function. I tried various methods that indicate start of the editing process, but none is called (but are called for standalone text fields). When I do not set the highlightColor then the editor color is correct but the highlight color of a selected row is wrong then.

Honestly, this is one of those things that you'd think would be really simple and straightforward, and it's really unfortunately not.

The only ways to affect the color in the field editor, are to either:

a) Set the color of your text field to the desired color before NSCell's selectWithFrame:... method is called b) Change the color the text placed into the field editor after selectWithFrame:... is called.

So generally:

a) subclass NSTextFieldCell and set the field's text color back to the usual default before the field editor is set up.

- (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) Change the field editor directly

- (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;
}

I had previously answered a related question. Not sure if this should be marked as duplicate: https://stackoverflow.com/a/54217318/217306

The gist is that the text editing mode is handled by a separate object called field editor . You should create a new instance and use it to customize the look during editing for your table.

windowWillReturnFieldEditor delegate method of NSWindow asks which editor to use for editing a client . You create such editor once for your table and return it when the delegate asks for an editor for your table.

- (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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM