Modifier la couleur de sélection sur NSTableView basé sur une vue

La couleur de mise en évidence standard dans les applications OS X est le bleu.

Est-il possible de le changer pour une autre couleur, par exemple le gris?

Notez que j’utilise le nouveau NSTableView basé sur une vue disponible à partir d’OS X 10.7.

Puisque vous utilisez la vue basée sur NSTableView, vous pouvez sous-classer NSTableRowView, la nourrir à la méthode de délégué de table - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row; , puis personnalisez votre sélection dans la classe d’affichage des lignes.

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

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 réglé sur YES, vous obtenez le surlignage bleu, alors que NO vous donne le surlignage gris.

 -(void)tableViewSelectionDidChange:(NSNotification *)aNotification { NSInteger selectedRow = [myTableView selectedRow]; NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO]; [myRowView setEmphasized:NO]; } 

Voici la solution de James Chen dans Swift 3. J’ai également ajouté la méthode des delegates.

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

Quelques modifications à la réponse de Jean-Pierre

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 réglé sur YES, vous obtenez le surlignage bleu, alors que NO vous donne le surlignage gris.

 -(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 du bleu puis du gris

 [_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone]; 

Lorsque vous utilisez Swift, vous pouvez le faire en 10.10 pour les cellules basées sur les vues

Sous-classe 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 mise en évidence NSTableView doit être défini sur Regular s’il se trouve sur SourceList cela entraînera un écrêtage étrange.

Ce n’est pas la solution la plus propre mais ça marche bien sur le yosemite

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 de l’une;
  • Toutes les frontières extérieures étranges et autres rests 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() } } } 

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

entrer la description de l'image ici

Comme déjà mentionné, définissez l’atsortingbut souligné sur false, mais faites-le dans la classe personnalisée NSTableRowView pour éviter les effets secondaires (comme l’effet de couleur de danse):

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

Vous devez sous- NSTableView et réécrire les fonctions ci-dessous afin de changer les couleurs en alternance.

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

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

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

Ok, donc je sais qu’il a déjà une réponse acceptée, mais pour quiconque comme moi travaille avec un NSOutlineView et que .selectionHighlightStyle = .sourceList peut utiliser ce code pour rendre la sélection grise. Cette méthode ne clignotera pas lors de la modification de la sélection et restra également grisée si l’application est réduite.

NSTableView / NSOutlineView Delegate:

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

Et puis créez 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.

C’est la réponse de Jean-Pierre dans Swift3:

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

Il a les deux limitations énumérées ci-dessus – le premier clic ne fonctionne pas, le deuxième clic le fait. Et, il y a un “effet de danse”. Le premier ne me dérange pas et en fait, j’aime le second.

 - (void)tableViewSelectionDidChange:(NSNotification *)notification { [tblCategory enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row){ CustomMainCell *cellView = [rowView viewAtColumn:0]; if(rowView.selected){ cellView.txtFieldTitle.textColor=[NSColor colorWithCalibratedRed:245.0/255.0 green:110.0/255.0 blue:65.0/255.0 alpha:1.0]; }else{ cellView.txtFieldTitle.textColor=[NSColor whiteColor]; } }]; } 

[tblCategory setSelectionHighlightStyle: NSTableViewSelectionHighlightStyleNone];

  Use this Notification for NSTableView: - (void)tableViewSelectionDidChange:(NSNotification *)notification { //You Logic stuff }