2010-11-23 16 views
24

estoy usando NSOutlineView para un proyecto, y parece que no puede averiguar dos cosas:NSOutlineView: eliminar triángulo desplegable y guión

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

alt text

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

  • Cómo deshabilitar la sangría de los elementos. He intentado usar setIndentationPerLevel: y establecerlo en 0, así como cambiar la sangría de la columna a 0 en el Interface Builder, pero no parece tener ningún efecto.

Respuesta

38

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

Extracción del triángulo desplegable: (. Sólo si desea ocultar el triángulo de esa fila en particular, por supuesto) poner en práctica el método frameOfOutlineCellAtRow: en su NSOutlineView subclase y volver NSZeroRect

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

Desactivar sangría: el diseño estándar de la vista de esquema reserva espacio en el extremo izquierdo para dibujar los triángulos, en caso de que el elemento sea expansible. Pero puede anular eso para elementos individuales especificando un marco de dibujo diferente. También hace que en la 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; 
} 
+0

Gracias! Voy a intentarlo – indragie

+0

Puede afectar la sangría sin subclasificar el outlineView estableciendo indentationMarkerFollowsCell en false. – pickwick

+0

realmente genial, gracias – melody5417

2

Uso PXSourceList. Es el estilo que estás buscando con una muy buena API.

+0

Gracias Dave, de hecho tiene una muy buena API. Estoy usando eso en combinación con la sugerencia de Marcel para eliminar la sangría para lograr lo que quería :-) – indragie

+0

Si usa PXSourceList puede lograr ese estilo al devolver 'SÍ' al mensaje' PXSourceListDelegate' '-sourceList: isGroupAlwaysExpanded:' para el grupo que quieres que se muestre así. –

+0

Muy buena referencia. PXSourceList parece un gran ahorro de tiempo. Gracias, Dave y especialmente Alex. :-) –

32

Para referencia futura, la manera más limpia y sencilla de ocultar el triángulo desplegable en ampliables NSOutlineView artículos está implementando el método del protocolo NSOutlineViewDelegateoutlineView:shouldShowOutlineCellForItem: 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]; 
} 
+3

Cuando intento hacer esto, ya no puedo colapsar (programáticamente) estos elementos. ¿Es esto un error de mi parte? –

+2

Este método de delegado no parece ser necesario para las vistas de esquema basadas en vista. En ese caso, encontré que establecer sangría a 0 en IB tenía el efecto deseado –

+0

Me gustaría saber dónde en IB para establecer que ... – uchuugaka

7

que tenía que combinar los dos enfoques más arriba porque outlineView:shouldShowOutlineCellForItem: por sí solo no elimina el espacio reservado para los triángulos de revelación (sí elimina los triángulos).

Delegado:

- (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:

Screenshot of NSOutlineView with no top-level indentation

+0

Tenga en cuenta que la columna 0 puede no ser la columna de contorno. Imagine las casillas de verificación de la izquierda para la inclusión (el mejor lugar para ellas, de modo que todas estén alineadas de la misma manera). Es mejor solicitar la vista de esquema para su -outlineTableColumn en lugar de asumir que es la columna 0. –

+0

En ese caso, use un identificador único para la columna. –

+0

Estoy de acuerdo con frameOfCellAtColumn: row: Pero devolviendo NO a outlineView: shouldShowOutlineCellForItem: evitará colapsar el elemento a partir de entonces – Christophe

-1

yo probamos este en Swift. Simplemente funciona. No sé si es una forma adecuada. No debería ser 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 que regrese YourHeaderCellClass elemento en el método fuente de datos.

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

Lamento rechazar su respuesta, pero esta es una forma muy peligrosa de hacerlo. Está haciendo suposiciones sobre el índice de subvistas en sus matrices, que es un detalle de implementación más allá de su control. Como en todas las cosas de Cocoa, es mejor no luchar contra el marco pero primero busque un método delegado que pueda anular (vea otras respuestas arriba). –

Cuestiones relacionadas