Créer sa propre classe TableView : problème d'affichage

Bonjour


 


Je souhaite créer une sous-classe de NSTableView. Donc via l'IB, j'ai dessiné dans un NSDocument, une NSTableView que j'ai renommé FDTableView (du nom de ma nouvelle classe).



Je fais passer les valeurs des tableaux grâce à  la méthode
self.valCol1 = [NSMutableArray arrayWithObjects:@Val1Col1,@Val2Col1, nil];
self.valCol2 = [NSMutableArray arrayWithObjects:@Val1Col2,@Val2Col2, nil];
self.valGlobale = [NSMutableArray arrayWithObjects:valCol1,valCol2, nil];


[maTableView initValWithTableau: self.valGlobale];

qui est placée dans la méthode windowControllerDidLoadNib de mon NSDocument. Mais lorsque je lance l'appli, le cadre de ma TableView s'affiche mais aucune données n'apparaissent.


 


Voici mon code FDTableView.h



#import <Cocoa/Cocoa.h>

@interface FDTableView : NSTableView <NSTableViewDelegate, NSTabViewDelegate, NSTableViewDataSource>
{

NSMutableArray *tableauDesVal;
NSMutableArray *idColonne;

}
@property (nonatomic, retain) NSMutableArray *tableauDesVal;
@property (nonatomic, retain) NSMutableArray *idColonne;

-(void)initValWithTableau:(NSMutableArray*)mesTabl;

@end

et FDTableView.m

-(void)initValWithTableau:(NSMutableArray*)mesTabl
{


self.tableauDesVal = [NSMutableArray arrayWithArray:mesTabl];
// la construction du tab se fait ds l'IB sans oublier de remplir les identifiants des colonnes

long nbCol = [self numberOfColumns];
//importer les identifiants des colonnes
NSArray *tabColonne = [NSArray arrayWithArray:[self tableColumns]];
self.idColonne = [[NSMutableArray alloc]init];
for (int i=0; i<nbCol; i++) {
NSString *val = [[tabColonne objectAtIndex:i] identifier];
if (val) {//si l'identifier est bien remplit
[idColonne addObject:val];

}else{
NSString *mess = [NSString stringWithFormat:@identifier de la colonne %i,i];
NSRunAlertPanel(mess, @n'est pas rempli, nil, nil, nil);
exit(1);
}
}


[self setDataSource:self];
[self setDelegate:self];
}

-(void)dealloc
{
[idColonne release];

[super dealloc];
}

#pragma mark -
#pragma mark delegé tableView

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [[tableauDesVal objectAtIndex:0] count];
}

//_____________________________________________________________________________

- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(long)row
{

for (int i=0; i<[idColonne count]; i++) {
if ([[tableColumn identifier] isEqualToString:[idColonne objectAtIndex:i]])
{
NSString *test = [[tableauDesVal objectAtIndex:i]objectAtIndex:row];
return [[tableauDesVal objectAtIndex:i] objectAtIndex:row];

}
}

return [[tableauDesVal objectAtIndex:0] objectAtIndex:row];// normalement on y passe pas

}


Qu'est ce que j'ai raté ???


 


Pour info, j'ai replacé les méthodes de FDTableView directement dans NSDocument (avec les NSTabViewDelegate, NSTableViewDataSource) et là , ça marche


Du coup, je pense que cela vient d'un délégate car il semble que ce ne soit qu'un pbl  d'affichage, mais je ne trouve pas


 


Merci d'avance


Réponses

  • CéroceCéroce Membre, Modérateur
    décembre 2013 modifié #2

    Je souhaite créer une sous-classe de NSTableView.

    Diable. Mais pourquoi ???
    Si c'était pour changer son apparence, j'aurais dit pourquoi pas, mais pas pour remplir la table. C'est au data source de fournir les données. Une NSTableView fait partir de la couche Vue du modèle MVC, elle n'a pas à  connaà®tre le modèle.

    Pour répondre à  ta question, commence par mettre des points d'arrêts dans les méthodes du data source, tu verras qu'elle sont sans doute appelées trop tôt.
  • En fait, je souhaite faire une class qui me permettrait de simplifier la mise en place des tableView avec boutons de suppression, d'ajout de sélection ... et bien sur de son apparence


     


    Pour les points d'arret, j'en ai bien sur mis et le NSString *test me donne bien les bonnes valeur, mais du coup, qu'entends tu pas trop tôt ?

  • CéroceCéroce Membre, Modérateur

    En fait, je souhaite faire une class qui me permettrait de simplifier la mise en place des tableView avec boutons de suppression, d'ajout de sélection ... et bien sur de son apparence

    à‰tudie plutôt les bindings Cocoa. Une fois que tu as un NSArray d'objets, les afficher dans une table prend moins de 2 mn en utilisant les bindings. NSArrayController possède des actions pour ajouter, supprimer, réordonner des objets.

    Pour les points d'arret, j'en ai bien sur mis et le NSString *test me donne bien les bonnes valeur, mais du coup, qu'entends tu pas trop tôt ?

    Quand la table va s'afficher, la méthode -initValWithTableau: n'aura peut-être pas encore été appelée, et donc, la table n'aura pas encore de data source et n'affichera rien.
  • Merci Céroce pour ces infos.


     


    Pour les Bindings, je dois reconnaitre que j'ai pas mal de difficultés avec ! J'ai bien vu un tuto mais je n'ai pas vu comment insérer des actions pour ajouter, supprimer .... Ceci étant, si tu as un tuto plus complet que le mien, je suis preneur.


     


    Pour le 2e point, pour résoudre cette éventualité, j'ai placé après l'appel de la méthode initValWithTableau: un [maTableView reloadData]; Ceci suppose donc que les valeurs sont bien rentrées et s'il y a un problème de timing, un reload devrait redessiner le tableau, donc avec la certitude d'avoir les valeurs déjà  rentrées, mais le tableau est toujours vide...


     


    Merci d'avance

  • MalaMala Membre, Modérateur


    Pour le 2e point, pour résoudre cette éventualité, j'ai placé après l'appel de la méthode initValWithTableau: un [maTableView reloadData]; Ceci suppose donc que les valeurs sont bien rentrées et s'il y a un problème de timing, un reload devrait redessiner le tableau, donc avec la certitude d'avoir les valeurs déjà  rentrées, mais le tableau est toujours vide...




    Commence par mettre un point d'arrêt sur la ligne du reloadData et contrôle avec le débogueur que ta dataSource est pas vide. A mon avis, c'est un problème de timing.

  • c'est normal que rien ne s'affiche


     


    ton tableau tableauDesVal est vide !


     


    fais juste un test:



    - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
    {

    return 1;

    }

    //_____________________________________________________________________________

    - (id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)tableColumn
    row:(long)row
    {

    return @ya bon cocoacafe.f;

    }


  • Désolé Devulder mais rien de mieux !!!

  • Ta méthode initValWithTableau est bien appelé dans ton prog ?


     


    Met un NSLog dans numberOfRowsInTableView pour voir si le dataSource est correct, sinon je vois pas trop le prb

  • Si si j'y passe...et moi non plus je ne comprends pas...


    Merci tout de même et bonnes fêtes si on ne s'écrit pas d'ici là 


  • personne, non personne ne fetera noël avant d'avoir résolu ce bug ! :)


     


    fais nous un zip qu'on puisse voir le problême !

  • berfisberfis Membre
    décembre 2013 modifié #12


    Je souhaite créer une sous-classe de NSTableView. Donc via l'IB, j'ai dessiné dans un NSDocument, une NSTableView que j'ai renommé FDTableView (du nom de ma nouvelle classe).




    Bonjour,


     


    Tu dis que tu as renommé ta NSTableView dans IB, mais est-ce que tu l'as déclarée comme étant une FDTableView dans l'Identity Inspector ?


  • J'ai trouvé.


     


    Dans le drawRect de ta table, tu n'appelles pas [super drawRect] pour obtenir le dessin de la superclasse. Et donc tu inhibes tout dessin, puisque ta routine ne fait rien.


     


    Ajoute:



    - (void)drawRect:(NSRect)dirtyRect
    {
    [super drawRect:dirtyRect];
    // Drawing code here.
    }


    et tu verras ta table afficher "y'a bon..."


  • Génial


     


    Merci à  tous et encore bonnes fêtes...

  • PS pour berfis : ton annotation est tellement vraie : "La différence entre la théorie et la pratique, c'est qu'en théorie, il n'y a pas de différence entre la théorie et la pratique."...

  • Bien, ben voila une appli qui vaut ce qu'elle vaut mais qui va peut être permettre d'aider de nombreux débutants qui en ont bavés avec les tableaux et les binding... Merci encore à  tous


     


  • En effet, ça marche. Je ne comprends pas la raison qui te fait utiliser un contrôleur pour la table de droite (pattern MVC) et non pour la table de gauche, où c'est la vue qui traite directement la commande (pattern non-MVC). Quelque chose que j'ai raté?


  • Non, en fait, j'ai voulu faire une sous classe de Tableview (vue de gauche) qui permet de donner des infos pour ceux qui comme moi ont eu des difficultés à  démarrer, quant à  la vue de gauche, elle utilise le binding, donc toujours pareil, pour le débutant, ça peut peut être permettre de donner des pistes ...

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