objective-c cocoa osx-lion nstableview

objective c - Cambiar el color de selección en NSTableView basado en vista



objective-c cocoa (13)

Al usar Swift puede hacer esto en 10.10 para ver celdas basadas

Subclass el NSTableCellView e implementar esto:

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

Tenga en cuenta que el estilo de resaltado NSTableView debe establecerse en Regular si está en SourceList , causará un recorte extraño.

Esta no es la solución más limpia, pero funciona bien en Yosemite

El color de resaltado estándar en las aplicaciones OS X es azul.

¿Es posible cambiarlo a otro color, por ejemplo, gris?

Tenga en cuenta que estoy utilizando el nuevo NSTableView basado en NSTableView disponible a partir de OS X 10.7.


Algunas modificaciones a la respuesta de Jean-Pierre

Use el siguiente código en respuesta al protocolo NSTableViewDelegate tableViewSelectionDidChange:

Obtenga NSTableRowView para la fila seleccionada y llame al método setEmphasized en él. Cuando setEmphasized se establece en SÍ, se obtiene el resaltado azul, cuando NO se obtiene el resaltado gris.

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

Y para evitar el efecto danzante del azul, el conjunto gris

[_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];


Aquí está la solución de James Chen en Swift 3. También he agregado el método de delegado.

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


Bien, entonces sé que ya tiene una respuesta aceptada, pero para cualquiera como yo que trabaje con un NSOutlineView y tiene .selectionHighlightStyle = .sourceList puede usar este código para hacer que la selección sea gris. Este método no parpadeará al cambiar la selección y también permanecerá gris si la aplicación se minimiza.

Delegado de NSTableView / NSOutlineView:

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

Y luego crea un nuevo archivo CustomRowView.swift con esto:

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

Esto mantendrá gris la selección en todo momento.


Como ya se mencionó, establezca el atributo enfatizado en falso, pero hágalo en la clase personalizada NSTableRowView para evitar los efectos secundarios (como el efecto de color de baile):

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


Dado que está utilizando la vista basada en NSTableView, puede subclase NSTableRowView, alimentarlo al método de delegado de tabla - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row; , luego personalice su selección en la clase de vista de filas.

Aquí hay un ejemplo:

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


Esta es la respuesta de Jean-Pierre en Swift3:

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

Tiene las dos limitaciones enumeradas anteriormente: el primer clic no funciona, el segundo clic lo hace. Y, hay un "efecto danzante". No me importa el primero y realmente me gusta el segundo.


He mezclado todos los métodos descritos anteriormente y obtuve un código que hace exactamente lo que quiero.

  • La selección no cambia el color de los campos de texto en el interior;
  • Las filas recuerdan la selección y el color de uno;
  • Aparecen bordes exteriores extraños y otras sobras.

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


Me parece que hay una opción disponible para cambiar esto porque la documentación dice tres estilos de selección y el estilo predeterminado en regular es azul, mira la imagen de abajo. Necesitas enviar un mensaje que no puedo entender ya que tengo nunca antes había desarrollado aplicaciones para mac ... ¡esperando que esto ayude ...!


Use el siguiente código en respuesta al protocolo tableViewSelectionDidChange :

Obtenga NSTableRowView para la fila seleccionada y llame al método setEmphasized en él. Cuando setEmphasized se establece en SÍ, se obtiene el resaltado azul, cuando NO se obtiene el resaltado gris.

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


NSTableView subclase NSTableView y reescribir las funciones siguientes para cambiar los colores alternativos.

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

  • (void) drawBackgroundInClipRect: (NSRect) clipRect ** Este para cambiar el color principal y alternativo **

Use un ciclo for e inserte este condicional (i % 2 == 0) para detectar filas impares y pares.


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


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