Основанный на представлении выбор NSTableView?

Я написал табличное представление на основе вида, например так:

и я рисую выделение с помощью NSTableRowView, код выглядит так:

- (void)drawRect:(NSRect)dirtyRect {
  [[NSColor clearColor] setFill];
  if (self.isClicked) {
    [[[NSColor blackColor] colorWithAlphaComponent:0.08] setFill];
  }
  NSRect rowViewRect = NSMakeRect(0, 0, 274, 72);
  NSBezierPath *path = [NSBezierPath bezierPathWithRect:rowViewRect];
  [path fill];
}

Но, наконец, я обнаружил, что TableRowView не находится над tableView, поэтому selectedColor не покрывает изображение и кнопку, это больше похоже на цвет фона, но мне нужно, чтобы выбранный TableRowView покрывал представление, как здесь:

Выбранный цвет покрывает изображение и кнопку. Я гуглил, но идей не нашел. Спасибо за помощь ~

1 ответ

Решение

Так что это немного сложно. Стратегия состоит в том, чтобы иметь наложенное цветное представление с альфа-каналом меньше 1 в NSTableCellView, а затем добавлять и удалять его в зависимости от выбора ячейки.

Во-первых, вам нужен NSView, который может установить цвет фона:

NSView_Background.h

@interface NSView_Background : NSView 
@property (nonatomic, strong) NSColor *background;
@end

NSView_Background.m

#import "NSView_Background.h"

@implementation NSView_Background

- (void)drawRect:(NSRect)dirtyRect {
    [self.background set];
    NSRectFill([self bounds]);
}

- (void)setBackground:(NSColor *)color {
    if ([_background isEqual:color]) return;

    _background = color;

    [self setNeedsDisplay:YES];
}
@end

Во-вторых, в своем подклассе NSTableCellView добавьте свойство NSView_Background:

#import "NSView_Background.h"

@interface
@property (nonatomic, strong) NSView_Background *selectionView;
@end

В-третьих, добавьте этот метод в подкласс NSTableCellView:

- (void)shouldShowSelectionView:(BOOL)shouldShowSelectionView {
    if (shouldShowSelectionView) {
        self.selectionView = [[NSView_Background alloc] init];
        [self.selectionView setBackground:[NSColor grayColor]];
        self.selectionView.alpha = 0.4;
        [self addSubview:self.selectionView];

        [self setNeedsDisplay:YES];   // draws the selection view
    } else {
        [self.selectionView removeFromSuperview];
        self.selectionView = nil;
    }
}

В-четвертых, добавьте это в drawRect в своем подклассе NSTableCellView:

- (void)drawRect:(NSRect)dirtyRect {
    if (self.selectionView)
        self.selectionView.frame = self.bounds;
}

Наконец, переопределите NSTableCellView:setBackgroundStyle:

- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
    switch (backgroundStyle) {
        case: NSBackgroundStyleDark:
            [self shouldShowSelectionView:YES];
            break;
        default:
            [self shouldShowSelectionView:NO];
            break;
    }
}

Я знаю, что это кажется глупым, но это единственный способ, которым я мог получить такое поведение. Надеюсь, что это помогает и удачи!

Другие вопросы по тегам