Multi-tableview

muqaddarmuqaddar Administrateur
06:10 modifié dans API AppKit #1
Salut cocoaistes,

Je voulais savoir qu'elle était la meilleure façon de gérer les tableView imbriquées (jusqu'à  5). On clique dans une lignedu premier tableview, ça nous trie le 2è tableView et ainsi de suite. Le contenu des tableaux est dans des plist avec une clé qui correspond à  l'ID de l'index du tableau précédent sélectionné.
Je me demandais s'il était utile de faire une classe pour chaque contenu de tableau, sachant que ces plist seront modifiés et étoffées ailleurs dans mon appli.

merci.
«13

Réponses

  • cbrandtcbrandt Membre
    06:10 modifié #2
    tu veux que la ligne sélectionnée de ta tableview soit en gras, c'est ça ?

    dans le delegate, modifie la cellule juste avant l'affichage, en fonction du contexte (ligne sélectionnée / non sélectionnée):

    <br />- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex<br />{<br />    NSCell   *cell;<br />    cell = [aTableColumn dataCell];<br />    if ([aTableView isRowSelected: rowIndex])<br />        [cell setFont: [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]]];<br />    else<br />        [cell setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];<br />}<br />
    
  • cbrandtcbrandt Membre
    06:10 modifié #3
    tableview ou outlineview ?
    dans le premier cas, un nsbrowser pourrait peut-être convenir ?
  • muqaddarmuqaddar Administrateur
    06:10 modifié #4
    Non, non, c'est bien tableView. :-)
    Et pas de browser.
  • cbrandtcbrandt Membre
    06:10 modifié #5
    dans 1100696603:

    On clique dans une lignedu premier tableview, ça nous trie le 2è tableView et ainsi de suite.

    tu veux dire que le contenu du 2ème tableview ne change pas, uniquement son critère de tri  ???

    dans 1100696603:

    le contenu des tableaux est dans des plist avec une clé qui correspond à  l'ID de l'index du tableau précédent sélectionné.
    Je me demandais s'il était utile de faire une classe pour chaque contenu de tableau, sachant que ces plist seront modifiés et étoffées ailleurs dans mon appli.

    je pense que dans ce cas tu pourrais stocker le contenu des tableview comme un dictionnaires  ou un array de dictionnaires, quitte à  utiliser des catégories (sur les dictionnaires) pour créer des fonctions permettant d'accéder plus facilement aux objets s'y trouvant (je ne sais pas si je suis très clair, là ...)

  • nucleusnucleus Membre
    06:10 modifié #6
    J'avoue que j'ai du mal à  imaginer à  quoi correspond ton concept de tableview imbriquées..
    Une petite capture ou un dessin peur-être?
  • 06:10 modifié #7
    Pourquoi ne pas dire directement "comme dans iTunes avec les genres, artistes et albums" ;)
  • muqaddarmuqaddar Administrateur
    06:10 modifié #8
    Oui, comme dans iTunes, mais je ne suis pas sûr que ce soit des tableView ds iTunes.
    En fait, comme le carnet d'adresse, on a les groupes (une tableView) et les entrées (une autre) soit 2 niveaux, moi je vais en avoir 5.
    Je pense utiliser des array de dictionnaires qui contiennent l'id de la précédente ligne sélectionnée (index) à  chaque fois, pour éliminer les entrées non concernées par cette ligne. Mais suis-je clair ?

  • cbrandtcbrandt Membre
    06:10 modifié #9
    si j'ai bien compris, tu affiches dans une tableview une *partie* du contenu d'un array en fonction de la sélection de la tableview précédente ? un peu comme un filtre ?

    ce qui m'amène à  ma question suivante: comment est fait ton modèle de données ? car c'est en fonction de ça que tu utilisera un(des) tableview, outlineview, browser, etc...

    un petit schéma avec les relations entre les éléments serait le bienvenu...
  • muqaddarmuqaddar Administrateur
    06:10 modifié #10
    Voilà  un petit shéma, 5 array, dont 3 découlent l'un de l'autre, mais les 5 trient le tableau général de ma classe Elément. Par défaut tous les éléments sont affichés ds le tableau général. A chaque fois qu'on sélectionne un critère dans un array, le contenu du tableau général diminue si ces éléments ne répondent plus au critère général.

    Ce que je voulais savoir, c'est si une classe Element suffit pour gérer tout ça et pour s'en sortir avec les tris, ou si on a besoin d'une classe par array.

    [Fichier joint supprimé par l'administrateur]
  • cbrandtcbrandt Membre
    06:10 modifié #11
    strictement parlant, tu n'as pas *besoin* d'une classe: tu peux gérer tous les éléments sous forme de array de dictionnaire et créer des catégories si tu veux avoir des méthodes d'accès plus faciles à  écrire (lesquelles feront simplement des objectForKey: set setObject:forKey)...
    de même pour pays, region, departement, groupe, catégorie:
    .h:
    <br />@class Element (NSMutableDictionnary)<br />...<br />- (NSString*) paysID;<br />...<br />@end<br />
    

    .m:
    <br />@class Element (NSMutableDictionnary)<br />...<br />- (NSString*) paysID<br />{<br />    return [self objectForKey: @&quot;paysID&quot;];<br />}<br />...<br />@end<br />
    
  • muqaddarmuqaddar Administrateur
    06:10 modifié #12
    Je connais pas bien la syntaxe que tu as employée là .
    C'est une catégorie de la classe Element mais le NSMutableDictionnary ?
    J'avais l'habitude de lire les catégories comme ça : @interface PrefsController (PrefsToolbarCategory) pour les catégories.

    D'autre part, certains des arrays doivent être éditables (deptArray par exemple).

    Je vois sinon que tu crée quand même une classe Element en plus des catégories.

  • cbrandtcbrandt Membre
    06:10 modifié #13
    euh, tu as raison, je me suis trompé dans la syntaxe :'(
    il s'agissait de créer une catégorie 'Element' pour la class nsmutabledictionary
  • nucleusnucleus Membre
    06:10 modifié #14
    Si j'ai bien compris, tu veux faire fonctionner ton groupe de NSTableView du haut (pays, région,dept)  comme un NSBrowser?

    A moins que tu veuilles dire filtrage au lieu de tri, pourquoi ne pas utiliser les entêtes des colonnes pour groups et categories?
  • muqaddarmuqaddar Administrateur
    06:10 modifié #15
    Oui, c'ets du filtrage en fait, je me suis mal exprimé. :-(
  • cbrandtcbrandt Membre
    06:10 modifié #16
    - donc tu pourrais utiliser un array (ou un dictionnaire avec les id comme clé) pour les pays/régions/départements, étant entendu que pour les pays, tu ajoutes un élément listeRégions, qui contient toutes les régions, et pour chaque région, tu ajoutes un élément listeDépartements, qui contient tous département. ceci pourrai être représenté par un nsbrowser (très utile pour ce cas)
    - une tableview pour les groupes
    - une tableview pour les catégories
    - et une tableview pour les éléments.

    - à  chaque fois que tu changes la sélection dans le browser pays/région/département, tu reconstruit ta liste des éléments
    - et si j'ai bien compris, à  chaque fois que tu changes la sélection dans la tableview des groupes ou dans la tableview des catégories, tu changes le tri dans la tableview des éléments (encore que je me demandes pourquoi on ne pourrait pas trier directement en cliquant sur les entêtes des colonnes concernées ???)

    et comme ça, ça devrait rouler...

  • muqaddarmuqaddar Administrateur
    06:10 modifié #17
    Un tableView se rebelle et refuse d'afficher son contenu... :-(

    Pourtant, j'ai NSLogué le array qui le remplit, il est parfait.
    Le datasource est bine connecté.
    Les identifiers sont bien renseignés dans IB.
    Outlet tableView bien connecté portant le même nom.

    A vrai dire, j'ai 2 tableView gérés par les méthodes de datasource. Il faut bien faire comme ça :

    -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex<br />{ <br />	if (aTableView == groupsTable) return [[groupsArray objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];<br />	if (aTableView == paysTable) return [[paysArray objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];<br />}<br />
    


    Pas de plantage, mais la tableView semble réagir avec scroller, mais n'affiche rien... :why?:
  • muqaddarmuqaddar Administrateur
    novembre 2004 modifié #18
    Bon, j'ai trouvé, l'array de mon controlleur principal et de celui du controller des prefs portaient le même nom, et apparemment ça ne plaisait pas à  ma tableView.

    Si quelqu'un a une idée sur le pourquoi de cette réaction ? Parce qu'ils sont chacun dans une classe indépendante l'une de l'autre avec des méthodes datasources dans chaque classe...

    D'autres part, il semblerait que mes 2 tableView (ds une meme classe) de veulent pas avoir toutes les 2 mainController pour datasource. C'ets le dernier connecté au datasource qui prend le pas sur l'autre...
  • muqaddarmuqaddar Administrateur
    06:10 modifié #19
    En fait, la tableView se charge bien, mais n'affiche rien au lancement de l'appli !!! En revanche si j'élargis un peu la fenêtre, ça doit la rafraichir et les champs s'affichent !!!
    Qui a une explication rationnelle à  cela ?
  • Eddy58Eddy58 Membre
    06:10 modifié #20
    dans 1100882825:

    En fait, la tableView se charge bien, mais n'affiche rien au lancement de l'appli !!! En revanche si j'élargis un peu la fenêtre, ça doit la rafraichir et les champs s'affichent !!!
    Qui a une explication rationnelle à  cela ?


    Dans ton initialisation, est-ce que tu fais bien un reloadData sur ta tableview après avoir initialisé ton array ?
  • muqaddarmuqaddar Administrateur
    06:10 modifié #21
    Dans le init, ça faisait rien, en revanche ds le awakeFromNib, ça semble marcher.
    Je pensais que le reload data c'était que quand on modifie le contenu du tableau non ?
  • Eddy58Eddy58 Membre
    06:10 modifié #22
    Oui, en parlant d'initialisation, je veux dire dans awakeFromNib dans ce cas, ce qui est normal car il faut attendre l'initialisation de tes objets nib pour pouvoir les utiliser. :)
    Oui justement, le contenu de ta tableView tu le modifies dès le début, en initialisant ton array, ce qui signifie qu'il faut ensuite rafraichir ta tableView pour la mettre à  jour selon les modifs de ton array.
  • muqaddarmuqaddar Administrateur
    novembre 2004 modifié #23
    OK, compris.
    Mercy Eddy !

    Par hasard, tu n'aurais pas la méthode qui permet de modifier la largeur d'une colonne ? Je n'ai rien trouvé ds la doc à  part sizeToFit qui ne fait pas cela...
    J'ai en effet pas moyen de rédurie une colonne ds IB alors je voudrais la forcer par le code.
  • Eddy58Eddy58 Membre
    06:10 modifié #24
    Et bien Oxitan tu te procures un pointeur sur la colonne dont tu veux modifier la taille, ensuite tu utilises dessus les méthodes de la classe NSTableColumn. Tu utilises la méthode setWidth:, et normalement ca devrait marcher, surveilles aussi tes largeurs minimums et maximums pour que la valeur que tu règles soit comprise entre les deux. D'après la doc, il faut apparemment faire un reloadData pour rafraichir ta tableView après avoir retailler la colonne. Enfin bon tu verras bien, essaye déjà  de la retailler... :)
  • muqaddarmuqaddar Administrateur
    06:10 modifié #25
    Mince, je n'avais pas vu les réglages de size ds IB... sur la sélection d'une colonne.
    Suffisait de changer la taille min.
    merci.
  • Eddy58Eddy58 Membre
    06:10 modifié #26
    Ha oui je trouvais ca bizarre aussi !  :) ;D
  • muqaddarmuqaddar Administrateur
    06:10 modifié #27
    dans 1100798827:

    - donc tu pourrais utiliser un array (ou un dictionnaire avec les id comme clé) pour les pays/régions/départements, étant entendu que pour les pays, tu ajoutes un élément listeRégions, qui contient toutes les régions, et pour chaque région, tu ajoutes un élément listeDépartements, qui contient tous département. ceci pourrai être représenté par un nsbrowser (très utile pour ce cas)
    - une tableview pour les groupes
    - une tableview pour les catégories
    - et une tableview pour les éléments.

    et comme ça, ça devrait rouler...


    Bon, j'en reviens à  mes moutons. Je suis têtu comme une bourrique, et je n'ai pas envie d'utiliser de NSBrowser pour les 3 tableaux qui découlent l'un de l'autre, mais bien 3 tableView distinctes.
    Je charge mes 3 arrays qui correspondent aux 3 tableView à  partir de mes 3 plists sachant que chaque enregistrement à  une clé qui se rapporte à  un Id d'une entrée du tableau précédent.

    Ce que je veux savoir, c'est comment ça se passe au niveau du filtrage. Le tableau avec toutes les lignes est tjs construit au départ, puis on affiche ou pas des lignes suivant la sélection de la ligne du tableau précédent, ou bien il faut recontsruire un tableau provisoire à  chaque nouvelle sélection ? (j'en doute, ça doit bouffer des ressources)
    Pour le moment, j'ai mes 3 arrays ds mes 3 tableView et ils affichent tout.

    Je voulais contrôler le filtrage avec :
    - (void)tableViewSelectionDidChange:(NSNotification *)aNotification <br />{<br />}
    


    qui surveille les changements de lignes sélectionnées ds mes tableView, mais comment lui faire comprendre sur quelle tableView agir et donc sur quelle ligne d'array ? Il n'y a pas de paramètres comme les méthodes datasource des tableView (row, column, atableView...).
  • mpergandmpergand Membre
    06:10 modifié #28
    Salut,


    mais comment lui faire comprendre sur quelle tableView agir

    NSTableView* table=[aNotification object];

    et donc sur quelle ligne d'array ?

    int selected=;
    etant donné que c'est DidChange ;)
  • muqaddarmuqaddar Administrateur
    06:10 modifié #29
    Super, j'ai fait des tests, ça a l'air de tourner nikel avec des NSLogs.
    Merci Monsieur mpergand.

    J'avais "peur" d'avoir besoin d'implémenter une notification en plus.
  • mpergandmpergand Membre
    06:10 modifié #30
    pas de quoi,

    mais c'est vrai que c'est vraimant zarbi ta serie de tableViews à  la chaine ;D ;D ;D
  • ClicCoolClicCool Membre
    06:10 modifié #31
    Salut :)

    ça manque furieusement de bindings dans le coin ;D

    Jettes un oeil à  ces exemples

    Filtering Controller est un exemple de filtrage d'un tableau géré par Binding.

    Combatants (tu connais je crois) est un exemple simpliste d'interraction entre 2 controllers

    Un petit mélange des 2 pourrait gérer tes tableViews non ?  ;)
Connectez-vous ou Inscrivez-vous pour répondre.