2010-11-23 5 views
24

J'utilise NSOutlineView pour un projet, et ne peut pas sembler comprendre deux choses:NSOutlineView: supprimer triangle et tiret

  • Comment enlever le triangle de divulgation pour les nœuds d'arbres. Des applications comme iTunes semblent être en mesure de le faire:

alt text

Y at-il une sorte de méthode NSOutlineView délégué qui est utilisé pour cela? Ou faut-il une sous-classe?

  • Comment désactiver l'indentation des éléments. J'ai essayé d'utiliser setIndentationPerLevel: et de le mettre à 0, ainsi que de modifier le retrait de colonne à 0 dans Interface Builder, mais cela ne semble pas avoir d'effet.

Répondre

38

Vous avez rencontré la bonne personne ici. J'ai dû me débattre avec ça il y a juste une semaine.

Retrait du triangle de divulgation: (. Seulement si vous voulez cacher le triangle de cette ligne particulière, bien sûr) mettre en œuvre la méthode frameOfOutlineCellAtRow: dans votre NSOutlineView sous-classe et retour NSZeroRect

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

Désactiver indenter: la disposition standard de la vue de contour réserve l'espace à l'extrême gauche pour dessiner les triangles, au cas où l'élément est extensible. Mais vous pouvez remplacer cela pour des éléments individuels en spécifiant un cadre de dessin différent. Vous faites également que dans votre sous-classe, en répondant à ce message:

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

Merci! Je vais essayer – indragie

+0

Vous pouvez affecter l'indentation sans sous-classer outlineView en définissant indentationMarkerFollowsCell à false. – pickwick

+0

vraiment cool, merci – melody5417

2

Utilisez PXSourceList. C'est le style que vous recherchez avec une très bonne api.

+0

Merci Dave, il a en effet une très belle API. J'utilise cela en combinaison avec l'astuce de Marcel pour supprimer le retrait afin d'obtenir ce que je voulais :-) – indragie

+0

Si vous utilisez PXSourceList, vous pouvez obtenir ce style en renvoyant 'YES' au message' PXSourceListDelegate' '-sourceList: isGroupAlwaysExpanded:' pour le groupe que vous voulez afficher comme ça. –

+0

Très belle référence. PXSourceList ressemble à un énorme gain de temps. Merci, Dave et surtout Alex. :-) –

32

Pour référence ultérieure, la plus propre et la plus simple de cacher le triangle de l'information présentée dans extensible NSOutlineView éléments est en mettant en œuvre la méthode outlineView:shouldShowOutlineCellForItem: du protocole NSOutlineViewDelegate dans votre délégué:

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

Lorsque j'essaie de faire cela, je ne peux plus (par programmation) réduire ces éléments. Est-ce une erreur de mon côté? –

+2

Cette méthode de délégation ne semble pas appelée pour les vues planifiées basées sur les vues. Dans ce cas, j'ai trouvé que mettre l'indentation à 0 dans IB avait l'effet désiré –

+0

Je voudrais savoir où dans IB pour définir cela ... – uchuugaka

7

je devais combiner les deux approches ci-dessus car outlineView:shouldShowOutlineCellForItem: seul ne supprime pas l'espace réservé aux triangles d'affichage (il supprime les triangles eux-mêmes).

Délégué:

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

Sous-classe 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 

Résultat:

Screenshot of NSOutlineView with no top-level indentation

+0

Notez que la colonne 0 peut ne pas être la colonne de contour. Imaginez des cases à cocher à gauche pour l'inclusion (le meilleur endroit pour eux afin qu'ils soient tous alignés de la même manière). Il est préférable de demander à la vue de plan pour son -outlineTableColumn plutôt que de supposer que c'est la colonne 0. –

+0

Dans ce cas, utilisez un identificateur unique pour la colonne. –

+0

Je suis d'accord pour frameOfCellAtColumn: row: Mais en retournant NON à outlineView: shouldShowOutlineCellForItem: empêchera de réduire l'élément par la suite – Christophe

-1

J'ai essayé à Swift. Cela fonctionne juste. Je ne sais pas si c'est un bon moyen. Il devrait y avoir équivalent 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) 
     } 
    } 
} 

Assurez-vous de retour YourHeaderCellClass article dans la méthode de source de données.

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

Désolé de baisser votre réponse, mais c'est une façon très dangereuse de le faire. Vous faites des suppositions sur l'index des sous-vues dans leurs tableaux, ce qui est un détail d'implémentation indépendant de votre volonté. Comme dans tout ce qui est Cocoa, il est préférable de ne pas combattre le framework mais d'abord rechercher une méthode déléguée que vous pouvez remplacer (voir les autres réponses ci-dessus). –