Sélection pour une NSTableCellView dérivée

Bonjour,


 


Comment indiquer qu'une NSTableCellView dérivée est sélectionnée? Cela parait, encore une fois, trivial " et ça l'est si on veut un comportement standard " mais dès qu'on veut quelque chose d'un poil différent... on galère.


 


Dans la copie d'écran jointe, vous avez à  gauche le comportement standard, et à  droite celui que je voulais obtenir, parce qu'il flattait davantage mon sens esthétique sans déroger aux HIG, grâce à  ma classe dérivée HomeworkCellView.


 


Cela m'a pris des heures de recherche, dans la doc et sur le web, en commençant par éliminer les sites qui ne convenait pas ou étaient des copies conformes les uns des autres. Et puis ce côté qui commence à  me porter sur les nerfs: je recherche "NSTableCellView" et Safari me demande: "voulez-vous dire UITableCellView"? Non, je fais partie des fossiles qui programment sur Mac, désolé.


 


J'ai fini par dénicher quelque chose qui fonctionne, mais je voulais savoir s'il existait plus simple, et sinon eh bien voici une solution.


 


Cela a été dit dans d'autres discussion, les view-based NSTableView tiennent de la surcouche bricolée, pour "faire de l'iOS" avec une vieille structure. Eh bien, la doc aussi a l'air bricolée.


 


Les NSTableCellView sont incluses en fait dans une classe "NSTableRowView" qui n'apparaà®t nulle part dans IB et que vous auriez de la peine à  dériver depuis le nib, il faudra le faire par code. Pourquoi la NSTableRowView? Parce que c'est elle qui est responsable du dessin de la sélection. Ce serait donc elle qu'il faudrait dériver mais... je ne voulais pas changer la couleur de la sélection de la ligne entière, mais celle de mon bezier dans le drawRect ma NSTableCellView.


 


Voici ma solution (je dis la mienne parce que, encore une fois, je voulais éviter la datasource):


 


J'utilise un NSArrayController dérivé pour gérer ma NSTableView. Il est déjà  là , parce qu'il gère des entités Core Data (pour rendre les choses encore plus savoureuses).


 


Il me faut savoir quand la sélection change. Je fais donc de mon contrôleur le délégué de ma tableView et j'implémente la méthode



- (void)tableViewSelectionDidChange:(NSNotification *)notification

qui m'envoie la tableView comme objet de la notification. Mais c'est là  que les choses se corsent un peu. Je peux retrouver (en cherchant un peu) la cellule sélectionnée, mais comment lui dire, à  elle, qu'elle est sélectionnée ? Je colle dans le .h de ma HomeworkCellView:



@property BOOL isSelected;

Ne reste plus qu'à  changer ce flag. Eh bien voici comment j'ai fait. Retour dans le contrôleur:



- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
[(NSTableView *)notification.object enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row){
NSTableCellView *cellView = [rowView viewAtColumn:0];
[(HomeworkCellView*)cellView setIsSelected:(rowView.selected)];
[cellView display];
}];
}

On y retrouve la fameuse NSTableRowView mentionnée plus haut. J'y mets mon flag à  jour, et je redemande le dessin (j'aurais pu demander needsDisplay) pour visualiser non seulement la nouvelle sélection, mais aussi supprimer l'ancienne.


 


On finit par le dessin de la cellule:



- (void)drawRect:(NSRect)dirtyRect
{
...
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect (self.bounds,4,4) xRadius:12 yRadius:12];
[path addClip];
NSColor *titleBandColor = [NSColor <whatever default color>];
...
if (self.isSelected) titleBandColor = [NSColor <selectionColor>];
[titleBandColor set];
NSRect r = NSMakeRect(0, self.bounds.size.height-30, 1000, 100); // Rect is clipped
NSRectFill(r);
[[NSColor blackColor]set];
[path stroke];
}

Et ça marche. Je suis donc satisfait, mais ça me paraà®t du bricolage sur du bricolage.


 


Pas à  vous?


 


Commentaires et suggestions bienvenus.


Réponses

  • Intéressant.

    J'ai regardé vite-fait, et sous iOS, on a setSelected:animated, mais sous Mac OS X, c'est un peu le néant les méthodes des tableviewCell...

    En bref, tu refais plus ou moins ce que fait déjà  sont équivalent sous iOS.


  • Et en spécifiant NSTableViewSelectionHighlightStyleNone dans la méthode setSelectionHighlightStyle: de NSTableView, ça donne quoi ?


     



     


    je recherche "NSTableCellView" et Safari me demande: "voulez-vous dire UITableCellView"? 



     


    Ce n'est pas Safari, c'est Google.




  • Et en spécifiant NSTableViewSelectionHighlightStyleNone dans la méthode setSelectionHighlightStyle: de NSTableView, ça donne quoi ?




     


    Alors, bien sûr, après on en vient aux détails que je n'ai pas mentionnés, mais tu as raison, il est utile de le préciser:


     


    Cette solution fonctionne si on inhibe la sélection de la NSTableView sous IB, en spécifiant None comme méthode de sélection. Sinon la table garde sa sélection rectangulaire qui vient s'ajouter à  la mienne, et le résultat est pire.



  • Ce n'est pas Safari, c'est Google.




    Qu'importe, il n'y en a pas un pour racheter l'autre.



  • En bref, tu refais plus ou moins ce que fait déjà  sont équivalent sous iOS.




    C'est ce que semblaient regretter d'autres membres du forum, AliGator ou Céroce, je ne sais plus, mais je sais que l'interface iOS a davantage évolué que MacOS. J'en comprends les raisons, mais je le regrette tout de même: un petit coup de fraà®cheur serait la bienvenue, comme, d'un point de vue élémentaire:


    - les boutons


    - les immondes tabViews


    - le hideux et rigide NSSegmentedControl...

Connectez-vous ou Inscrivez-vous pour répondre.