objective-c cocoa nsoutlineview nstreecontroller

objective c - NSOutlineView: elimina el triángulo de divulgación y la sangría



objective-c cocoa (5)

Estoy usando NSOutlineView para un proyecto y parece que no puedo resolver dos cosas:

  • Cómo eliminar el triángulo de revelación para nodos de árbol. Las aplicaciones como iTunes parecen ser capaces de hacer esto:

¿Hay algún tipo de método NSOutlineView Delegate que se utiliza para esto? ¿O requiere una subclase?

  • Cómo deshabilitar la sangría para los artículos. He intentado usar setIndentationPerLevel: y configurándolo en 0, así como cambiando la sangría de la columna a 0 en Interface Builder, pero no parece tener ningún efecto.

Intenté esto en Swift. Simplemente funciona. No sé si es una forma adecuada. Debería haber equivalente en Obj-C:

extension NSTableRowView { override open func layout() { super.layout() if let cell = subviews.first as? NSTableCellView, cell.objectValue is <YourHeaderCellClass> { subviews.first?.setFrameOrigin(NSZeroPoint) } } }

Asegúrese de devolver el elemento YourHeaderCellClass en el método de fuente de datos.

func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any


Para futuras referencias, la forma más limpia y sencilla de ocultar el triángulo de divulgación en los elementos NSOutlineView expandibles es mediante la implementación del outlineView:shouldShowOutlineCellForItem: del protocolo NSOutlineViewDelegate en su delegado:

-(BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item { // replace this with your logic to determine whether the // disclosure triangle should be hidden for a particular item return [item hidesDisclosureTriangle]; }


Te has encontrado con la persona adecuada aquí. Tuve que lidiar con esto hace solo una semana.

Eliminación del triángulo de revelación : implemente el método frameOfOutlineCellAtRow: en su subclase NSOutlineView y devuelva NSZeroRect (solo si desea ocultar el triángulo de esa fila en particular, por supuesto).

- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row { return NSZeroRect; }

Desactivar sangría : el diseño estándar de la vista de contorno reserva espacio en el extremo izquierdo para dibujar los triángulos, en caso de que el elemento sea expandible. Pero puede anular eso para elementos individuales especificando un marco de dibujo diferente. También haces eso en tu subclase, respondiendo a este mensaje:

- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row { NSRect superFrame = [super frameOfCellAtColumn:column row:row]; if ((column == 0) /* && isGroupRow */) { return NSMakeRect(0, superFrame.origin.y, [self bounds].size.width, superFrame.size.height); } return superFrame; }


Tuve que combinar los dos enfoques anteriores porque outlineView:shouldShowOutlineCellForItem: solo no elimina el espacio reservado para los triángulos de divulgación (sí elimina los triángulos mismos).

Delegar:

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item { return NO; }

Subclase de NSOutlineView:

@implementation ExpandedOutlineView #define kOutlineCellWidth 11 #define kOutlineMinLeftMargin 6 - (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row { NSRect superFrame = [super frameOfCellAtColumn:column row:row]; if (column == 0) { // expand by kOutlineCellWidth to the left to cancel the indent CGFloat adjustment = kOutlineCellWidth; // ...but be extra defensive because we have no fucking clue what is going on here if (superFrame.origin.x - adjustment < kOutlineMinLeftMargin) { NSLog(@"%@ adjustment amount is incorrect: adjustment = %f, superFrame = %@, kOutlineMinLeftMargin = %f", NSStringFromClass([self class]), (float)adjustment, NSStringFromRect(superFrame), (float)kOutlineMinLeftMargin); adjustment = MAX(0, superFrame.origin.x - kOutlineMinLeftMargin); } return NSMakeRect(superFrame.origin.x - adjustment, superFrame.origin.y, superFrame.size.width + adjustment, superFrame.size.height); } return superFrame; } @end

Resultado:


Utilice PXSourceList . Es el estilo que buscas con una muy buena api.