NSTextField in NSTableCellView

2020-02-26 11:31发布

问题:

I have a view based NSTableView with a custom NSTableCellView. This custom NSTableCellView has several labels (NSTextField). The whole UI of the NSTableCellView is built in IB.

The NSTableCellView can be in a normal state and in a selected state. In the normal state all text labels should be black, in the selected state they should be white.

How can I manage this?

回答1:

Probably the easiest way to accomplish this would be to subclass NSTextField and to override the drawRect: method in your subclass. There you can determine whether the NSTableCellView instance containing your NSTextField instances is currently selected by using this code (which I use with a NSOutlineView, but it should also work with NSTableView):

BOOL selected = NO;
id tableView = [[[self superview] superview] superview];
if ([tableView isKindOfClass:[NSTableView class]]) {
    NSInteger row = [tableView selectedRow];
    if (row != -1) {
        id cellView = [tableView viewAtColumn:0 row:row makeIfNecessary:YES];
        if ([cellView isEqualTo:[self superview]]) selected = YES;
    }
}

Then draw the view like this:

if (selected) {
    // set your color here
    // draw [self stringValue] here in [self bounds]
} else {
    // call [super drawRect]
}


回答2:

Override setBackgroundStyle: on the NSTableCellView to know when the background changes which is what affects what text color you should use in your cell.

For instance:

- (void)setBackgroundStyle:(NSBackgroundStyle)style
{
    [super setBackgroundStyle:style];

    // If the cell's text color is black, this sets it to white
    [((NSCell *)self.descriptionField.cell) setBackgroundStyle:style];

    // Otherwise you need to change the color manually
    switch (style) {
        case NSBackgroundStyleLight:
            [self.descriptionField setTextColor:[NSColor colorWithCalibratedWhite:0.4 alpha:1.0]];
            break;

        case NSBackgroundStyleDark:
        default:
            [self.descriptionField setTextColor:[NSColor colorWithCalibratedWhite:1.0 alpha:1.0]];
            break;
    }
}

In source list table views the cell view's background style is set to Light, as is its textField's backgroundStyle, however the textField also draws a shadow under its text and haven't yet found exactly what is controlling that / determining that should it happen.



回答3:

This works no matter what style the table view has:

- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
    [super setBackgroundStyle:backgroundStyle];
    NSTableView *tableView = self.enclosingScrollView.documentView;
    BOOL tableViewIsFirstResponder = [tableView isEqual:[self.window firstResponder]];
    NSColor *color = nil;
    if(backgroundStyle == NSBackgroundStyleLight) {
        color = tableViewIsFirstResponder ? [NSColor lightGrayColor] : [NSColor darkGrayColor];
    } else {
        color = [NSColor whiteColor];
    }
    myTextField.textColor = color;
}


回答4:

Swift 4

 override var backgroundStyle: NSView.BackgroundStyle {
     get {
        return super.backgroundStyle
     }
     set {
        self.yourCustomLabel.textColor = NSColor(calibratedWhite: 0.0, alpha: 1.0)//black
     }
 }