web-dev-qa-db-fra.com

Changer la couleur de sélection sur NSTableView basé sur la vue

La couleur de surbrillance standard dans les applications OS X est le bleu.

Est-il possible de changer de couleur, par exemple gris?

Notez que j'utilise la nouvelle NSTableView basée sur la vue disponible à partir de OS X 10.7.

41
Dev

Puisque vous utilisez NSTableView basé sur la vue, vous pouvez sous-classer NSTableRowView, le nourrir à la méthode de délégation de la table - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row;, puis personnaliser votre sélection dans la classe de vue de ligne.

Voici un exemple:

- (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];
    }
}
74
James Chen

Voici la solution de James Chen dans Swift 3. J'ai également ajouté la méthode des délégués.

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()
}
13
Felix

Utilisez le code suivant en réponse au protocole NSTableViewDelegatetableViewSelectionDidChange:

Obtenez la NSTableRowView pour la ligne sélectionnée et appelez la méthode setEmphasized dessus. Lorsque setEmphasized est réglé sur OUI, vous obtenez la surbrillance bleue, sur NON, sur grise. 

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

     NSInteger selectedRow = [myTableView selectedRow];
     NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
     [myRowView setEmphasized:NO];
}
12
Jean-Pierre

Quelques modifications à Jean-Pierre answer

Utilisez le code suivant en réponse au protocole NSTableViewDelegate tableViewSelectionDidChange:

Obtenez le NSTableRowView pour la ligne sélectionnée et appelez la méthode setEmphasized sur celle-ci. Lorsque setEmphasized est défini sur YES, vous obtenez la surbrillance bleue, sur NON, la surbrillance grise.

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

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

Et pour éviter l'effet de danse bleu puis gris 

[_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
6
Utkarsha

J'ai mélangé toutes les méthodes décrites précédemment et obtenu un code qui fait exactement ce que je veux.

  • La sélection ne change pas la couleur des champs de texte à l'intérieur;
  • Les rangées se souviennent de la sélection et de la couleur d'une
  • Toutes les frontières extérieures et autres restes étranges apparaissent.

    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
dimazava

Lorsque vous utilisez Swift, vous pouvez le faire le 10.10 pour les cellules basées sur la vue.

Sous-classe la NSTableCellView et implémentez ceci:

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

Notez que le style de surbrillance NSTableView doit être défini sur Regular s'il est sur SourceList, cela entraînera un écrêtage étrange.

Ce n'est pas la solution la plus propre, mais cela fonctionne bien sur yosemite 

2
arnoapp

Il me semble qu’il existe une option disponible pour changer cela car la documentation dit trois styles de sélection et le style par défaut est le bleu, regardez l’image ci-dessous .. vous devez lui envoyer un message que je ne peux pas comprendre car j’ai jamais développé d'applications pour mac auparavant .. en espérant que cela aide ...!

enter image description here

1
Ankit Srivastava

Comme déjà mentionné, définissez l'attribut accentué sur false, mais faites-le dans la classe personnalisée NSTableRowView pour éviter les effets secondaires (comme un effet de couleur dansante):

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

    }
1
Lubos

Vous devez sous-classer NSTableView et réécrire les fonctions ci-dessous afin de changer les couleurs alternées.

  • (void) drawRow: (NSInteger) row clipRect: (NSRect) clipRect

  • (void) drawBackgroundInClipRect: (NSRect) clipRect ** Celui-ci pour changer la couleur principale et alternative **

Utilisez une boucle for et insérez ce (i % 2 == 0) conditionnel pour détecter les lignes impaires et paires.

0
Julian

Bon, je sais donc que sa réponse est déjà acceptée, mais quiconque comme moi travaille avec une variable NSOutlineView et a .selectionHighlightStyle = .sourceList peut utiliser ce code pour rendre la sélection grisée. Cette méthode ne clignotera pas lors du changement de sélection et restera également grise si l'application est réduite.

Délégué NSTableView/NSOutlineView:

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

     return row
}

Et créez ensuite un nouveau fichier CustomRowView.Swift avec ceci:

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

Cela gardera la sélection grise à tout moment.

0
Silicone