Изменить цвет выделения на основе представления NSTableView - PullRequest
42 голосов
/ 27 февраля 2012

Стандартный цвет подсветки в приложениях OS X - синий.

Можно ли изменить его на другой цвет, например серый

Обратите внимание, что я использую новый основанный на представлении NSTableView, доступный начиная с OS X 10.7.

Ответы [ 13 ]

74 голосов
/ 07 марта 2012

Поскольку вы используете NSTableView на основе представления, вы можете создать подкласс NSTableRowView, передать его методу делегата таблицы - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row;, а затем настроить свой выбор в классе представления строки.

Вот пример:

- (void)drawSelectionInRect:(NSRect)dirtyRect {
    if (self.selectionHighlightStyle != NSTableViewSelectionHighlightStyleNone) {
        NSRect selectionRect = NSInsetRect(self.bounds, 2.5, 2.5);
        [[NSColor colorWithCalibratedWhite:.65 alpha:1.0] setStroke];
        [[NSColor colorWithCalibratedWhite:.82 alpha:1.0] setFill];
        NSBezierPath *selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:6 yRadius:6];
        [selectionPath fill];
        [selectionPath stroke];
    }
}
14 голосов
/ 30 сентября 2016

Вот решение Джеймса Чена в Swift 3. Я также добавил метод делегата.

class MyNSTableRowView: NSTableRowView {

    override func drawSelection(in dirtyRect: NSRect) {
        if self.selectionHighlightStyle != .none {
            let selectionRect = NSInsetRect(self.bounds, 2.5, 2.5)
            NSColor(calibratedWhite: 0.65, alpha: 1).setStroke()
            NSColor(calibratedWhite: 0.82, alpha: 1).setFill()
            let selectionPath = NSBezierPath.init(roundedRect: selectionRect, xRadius: 6, yRadius: 6)
            selectionPath.fill()
            selectionPath.stroke()
        }
    }
}

NSTableViewDelegate:

func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
    return MyNSTableRowView()
}
12 голосов
/ 26 февраля 2013

Используйте следующий код в ответ на протокол NSTableViewDelegate tableViewSelectionDidChange:

Получите NSTableRowView для выбранной строки и вызовите метод setEmphasized для нее. Когда для setEmphasized установлено значение YES, вы получаете синюю подсветку, а если NO - серый.

-(void)tableViewSelectionDidChange:(NSNotification *)aNotification {

     NSInteger selectedRow = [myTableView selectedRow];
     NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
     [myRowView setEmphasized:NO];
}
6 голосов
/ 04 декабря 2014

Некоторые модификации Жан-Пьер ответ

Используйте следующий код в ответ на таблицу протокола NSTableViewDelegate tableViewSelectionDidChange:

Получите NSTableRowView для выбранной строки и вызовите для него метод setEmphasized. Когда для setEmphasized установлено значение YES, вы получаете синюю подсветку, а если NO - серую подсветку.

-(void)tableViewSelectionDidChange:(NSNotification *)aNotification {

 NSInteger selectedRow = [myTableView selectedRow];
 NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
[myRowView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];
[myRowView setEmphasized:NO];
}

А чтобы избежать танцевального эффекта синего, то и серого набора

[_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
3 голосов
/ 07 августа 2017

Я смешал все методы, описанные ранее, и получил код, который точно делает то, что я хочу.

  • Выделение не меняет цвет текстовых полей внутри;
  • Ряды запоминают выделение и цвет одного;
  • Появляются любые странные внешние границы и другие остатки.

    class AudioCellView: NSTableRowView {
    
        override func draw(_ dirtyRect: NSRect) {
            super.draw(dirtyRect)
            self.wantsLayer = true
            self.layer?.backgroundColor = NSColor.white.cgColor
        }
    
        override var isEmphasized: Bool {
            set {}
            get {
                return false
            }
        }
    
        override var selectionHighlightStyle: NSTableView.SelectionHighlightStyle {
            set {}
            get {
                return .regular
            }
        }
    
        override func drawSelection(in dirtyRect: NSRect) {
            if self.selectionHighlightStyle != .none {
                let selectionRect = NSInsetRect(self.bounds, 2.5, 2.5)
                NSColor(calibratedWhite: 0.85, alpha: 0.6).setFill()
                let selectionPath = NSBezierPath.init(rect: selectionRect)
                selectionPath.fill()
            }
        }
    }
    
2 голосов
/ 28 января 2016

Как уже упоминалось, установите выделенный атрибут на false, но сделайте это в пользовательском классе NSTableRowView, чтобы избежать побочных эффектов (например, эффекта танцующего цвета):

    override func drawRect(dirtyRect: NSRect) {
       super.drawRect(dirtyRect)
       self.emphasized = false

    }
2 голосов
/ 11 февраля 2015

При использовании Swift вы можете сделать это 10.10 для ячеек, основанных на представлении

Подкласс NSTableCellView и реализовать это:

//override to change background color on highlight
override var backgroundStyle:NSBackgroundStyle{
    //check value when the style was setted
    didSet{
        //if it is dark the cell is highlighted -> apply the app color to it
        if backgroundStyle == .Dark{
            self.layer!.backgroundColor = yourColor
        }
        //else go back to the standard color
        else{
            self.layer!.backgroundColor = NSColor.clearColor().CGColor
        }
    }
}

Обратите внимание, что стиль выделения NSTableView должен быть установлен на Regular, если он включен SourceList, это приведет к некоторому странному отсечению.

Это не самое чистое решение, но оно хорошо работает на йосемите

1 голос
/ 27 февраля 2012

Мне кажется, что есть возможность изменить это, потому что в документации сказано, что три стиля выбора и стандартный стиль по умолчанию - синий, посмотрите на изображение ниже ... вам нужно отправить ему сообщение, которое я не могу выяснитькак я никогда раньше не разрабатывал приложения для Mac ... надеюсь, что это поможет ...!

enter image description here

0 голосов
/ 22 марта 2017

Это ответ Жан-Пьера в Swift3:

func tableViewSelectionDidChange(_ notification: Notification)
    { 
        index = tableView.selectedRow
        let rowView = tableView.rowView(atRow: index, makeIfNecessary: false)
        rowView?.isEmphasized = false
...

У него есть два ограничения, перечисленных выше: первый щелчок не работает, второй щелчок.И есть «танцевальный эффект».Я не возражаю против первого и на самом деле люблю второе.

0 голосов
/ 05 января 2017

Хорошо, я знаю, что у него уже есть принятый ответ, но для любого, как я, работающего с NSOutlineView и имеющего .selectionHighlightStyle = .sourceList, можно использовать этот код, чтобы сделать выбор серым.Этот метод не будет мерцать при изменении выбора, а также останется серым, если приложение свернуто.

NSTableView / NSOutlineView Делегат:

func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView?
{
     let row : CustomRowView = CustomRowView.init()
     row.identifier = "row"

     return row
}

А затем создайте новый файл CustomRowView.swift сthis:

class CustomRowView : NSTableRowView
{
    override var isEmphasized: Bool {
        get { return self.isEmphasized }
        set(isEmp) { self.isEmphasized = false }
    }
}

Это позволит сохранить выделение серым всегда.

...