IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Apple Discussion :

[DEV] Cocoa/Obj-C : première appli : TODO


Sujet :

Apple

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 189
    Par défaut [DEV] Cocoa/Obj-C : première appli : TODO
    Bonjou,

    j'ai commencé hier à me familiariser avec XCode pour développer une première application Cocoa/Obj-C. Mon idée est de faire une application bidon genre qui permet de créer une tâche à effectuer, avec ou sans rappel.

    Pour le moment, j'aimerai simplement afficher dans un NSTableView les différentes tâches qui je rajoute au fur et à mesure. J'ai donc un bouton Add, qui m'ouvre une deuxieme fenetre dans laquelle je saisi un texte puis je la valide en appuyant sur un bouton Valider. Pour le moment le texte tappé s'affiche sur la sortie standard(NSLog) mais le reloadData ne fait pas afficher le texte le NSTableView. Pourtant je pense avoir correctement implémenter le controleur de Datasource.

    SI vous pouviez m'éclairer ce serait sympa.

    Voici mes deux classes :

    TODO.h
    /* TODO */

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #import <Cocoa/Cocoa.h>
    
    @interface TODO : NSObject
    {
    	IBOutlet NSTableView* tableTodo ;
    	IBOutlet NSTableView* tableDone ;
    	NSMutableArray* todoList ;
    	IBOutlet NSTabView* tabView ;
    	IBOutlet NSButton* buttonAdd ;
    	IBOutlet NSTextField* textTodo ;
    }
    
    - (id)initTODO:(id)sender;
    - (IBAction)addTodo:(id)sender;
    - (IBAction)deleteTodo:(unsigned int)ident;
    - (IBAction)doneTodo:(unsigned int)ident;
    
    
    @end
    TODO.m

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #import "TODO.h"
    
    @implementation TODO
    
    - (id)initTODO:(id)sender
    {
    	if(![super init])
    	return nil ;
    	
    	todoList = [NSMutableArray arrayWithCapacity:10]  ;
    	//[tableTodo setDataSource: todoList];
    
    	
    	return self ;
    
    }
    
    
    - (IBAction)addTodo:(id)sender
    {
    	[todoList addObject:[textTodo stringValue]] ;
    	[todoList reloadData];
    	
    }
    
    - (IBAction)deleteTodo:(unsigned int)ident
    {
    	[todoList removeObjectAtIndex:ident];
    
    
    }
    
    - (IBAction)doneTodo:(unsigned int)ident
    {
    
    
    }
    
    
    @end
    listController.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    /* listController */
    
    #import <Cocoa/Cocoa.h>
    
    @interface listController : NSObject
    {
    	@private
    	NSArray     *aBuffer;
    }
    @end
    listController.m
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #import "listController.h"
    
    @implementation listController
      - (int)numberOfRowsInTableView:(NSTableView *)aTable
    {
    		return ([aBuffer count]);
    }
           
    - (id)tableView:(NSTableView *)aTable objectValueForColumn:(NSTableColumn *)aCol row:(int)aRow
    {
    		return ([aBuffer objectAtIndex:aRow]);
    }
           
        
    @end

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 309
    Par défaut
    Je sais pas si c'est tellement bidon... comme application. Enfin toujours est-il que t'essaye de faire une "grosse" application sans base Cocoa ni Objective-C...

    Pour commencer, essaye de faire des noms conventionnels pour tes classes, le nom de la classe commence avec une majuscule puisque chaque nouveau mot contient une majuscule, donc il vaudrait mieux faire une classe ToDo et une classe ListController.

    À part ça. Dans ton nib tu dois avec une instance de la classe TODO... À part les objets déjà implémentés dans IB, tous les autres reçoivent un message "init" pour être initialisé, alors je te conseille de supprimer ton initTODO: par un simple -init.

    Ensuite, le data source d'un NSTableView ne peut être un NSMutableArray, il faut que tu crées un classe (ou que tu utilises ta TODO) qui sera la classe Data Source et qui fournira les données que la NSTableView demande (d'ailleurs évite de considérer return comme une fonction, les parenthèses ne servent à rien autour des messages Objective-C).

    À mon avis ta classe listController est inutile. Ce qu'il faut que tu fasses c'est définir ta classe ToDo comme data source de tes deux NSTableView et selon la NSTableView qui réclame ses données tu choisis de quel tableau tu veux retourner les données. Donc tes méthodes -tableView:objectValueForTableColumn:row: et numberOfRowsInTableView: doivent être définies dans ta classe.
    Tu peux aussi définir la méthode -tableView:setObjectValue:forTableColumn:row: pour pouvoir modifier les données directement dans le tableau.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 189
    Par défaut
    d'accord,

    j'ai donc effectué les modifications au niveau des noms de fichier et de classe, puis j'ai supprimé la classe listController.

    Par contre, je ne vois pas comment transformer ma classe Todo pour que celle-ci soit controller d'un NSTableView qu'elle contient.

    Les 3 méthodes à implémentées doivent être dans la classe Todo ?

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 309
    Par défaut
    ToDo ne contient pas la NSTableView, elle possède une référence vers la NSTableView. Ce qu'il faut faire c'est soit tu lies ton NSTableView et ton ToDo dans IB soit tu le fais dans l'initialisation de ToDo.
    La prelière technique tu fais un ctrl + clic sur ton NSTableView dans IB et tu glisses vers le cube qui représentes l'instance de ToDo, tu choisis "dataSource" dans l'inpsecteur.

    Ou alors 2ème technique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    - (id)init
    {
        self = [super init]
        if(self != nil)
        {
            todoList = [[NSMutableArray alloc] initWithCapacity:10];
            [tableTodo setDataSource:self];
        }
        return self;
    }
    Il ne faut pas oublier de faire la méthode -dealloc pour faire un release sur "todoList".

    Et ensuite les 3 méthodes que je t'ai indiqué tu les fais donc bien dans ta classe ToDo.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 189
    Par défaut
    pour le moment j'ai quelque chose comme celà :

    Todo.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #import <Cocoa/Cocoa.h>
    
    
    @interface Todo : NSObject
    {
    	IBOutlet NSTableView* tableTodo ;
    	IBOutlet NSTableView* tableDone ;
    	NSMutableArray* todoList ;
    	IBOutlet NSTabView* tabView ;
    	IBOutlet NSButton* buttonAdd ;
    	IBOutlet NSTextField* textTodo ;
    	
    }
    
    - (id)init:(id)sender;
    - (IBAction)addTodo:(id)sender;
    - (IBAction)deleteTodo:(unsigned int)ident;
    - (IBAction)doneTodo:(unsigned int)ident;
    - (int)numberOfRowsInTableView:(NSTableView *)aTable;       
    - (id)tableView:(NSTableView *)aTable objectValueForColumn:(NSTableColumn *)aCol row:(int)aRow;
    - (void)tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
    Todo.m
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #import "TODO.h"
    
    @implementation Todo
    
    - (id)init:(id)sender
    {
    	if(![super init])
    	return nil ;
    	
    	todoList = [NSMutableArray array] ;
    	
    	[tableTodo setDataSource:self];
    	
    	return self ;
    
    }
    
    
    - (IBAction)addTodo:(id)sender
    {
    	[todoList addObject:[textTodo stringValue]] ;
    	[tableTodo reloadData];
    	
    	
    }
    
    - (IBAction)deleteTodo:(unsigned int)ident
    {
    	[todoList removeObjectAtIndex:ident];
    	[tableTodo reloadData];
    
    }
    
    - (IBAction)doneTodo:(unsigned int)ident
    {
    
    
    }
    
    - (int)numberOfRowsInTableView:(NSTableView *)aTable
    {
    		return ([todoList count]);
    }
           
    - (id)tableView:(NSTableView *)aTable objectValueForColumn:(NSTableColumn *)aCol row:(int)aRow
    {
    		return ([todoList objectAtIndex:aRow]);
    }
    
    - (void)tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
    {
    	[todoList addObject:[textTodo stringValue]];
    }
    
    @end

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 189
    Par défaut
    pourquoi ma classe Todo ne contiendrait pas mon NSTableView ? C'est comme un NSButton ... il faut faire le lien entre le "NSOutlet NSButton *bouton" de la classe et le bouton de IB... mais ce sont pas des objets ce sont des références (NSButton *) avec lesquels on fait le lien avec le glisser déposer.

    l'ajout dans mon NSMutableArray doit se faire

    dans la méthode addTodo() ou dans la méthode à implémenter permettant d'ajouter un élément dans le DataSource ?

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 309
    Par défaut
    Déjà tu lis à moitié, quand j'ai dit "elle ne contient pas la NSTableView" j'ai rajouté "elle contient une référence vers la NSTableView" ce n'est pas pareil. Ensuite, pourquoi tu mets un argument à init ? D'où il sort le (id)sender ? C'est pas une action ! La méthode c'est :

    Rien de plus ! Ton application ne peut pas appeler -init: sur un objet d'une archive NIB. Donc tu me vires ce -init: et dans l'interface et dans IB !

    Ensuite, si tu utilises la méthode : +[NSArray array] pour créer ta ToDo list je te garantit un plantage après le premier clic, car l'objet qui en résultera sera supprimé très rapidement. Il faut soit que tu envoies un message -retain à l'objet soit que tu utilises le couple alloc/init.

    Sinon addTodo: et deleteTodo: semble... bonnes, pour le reste tu t'y prends vraiment à l'arrache, j'aimerais savoir si t'as seulement chercher à comprendre l'intérêt des méthodes que je t'ai indiqué, regarde la doc ! et tu verras que ta tableView:setObjectValue:... c'est de la <bip>...

    L'ajoute de nouveaux todo doit se faire dans addTodo: pas autre part, il faut être cohérent. tableView:setObjectValue: permet de MODIFIER le contenu d'un de tes todo en lui donnant la valeur de l'argument setObjectValue:...

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 189
    Par défaut
    En fait, je pensais que la méthode tableView:setObjectValue faisait la même chose que ma méthode addTodo ... j'ai fait les modifications je sais pas si c'est correct. Mais l'enervement que tu as pu déceler dans mon post ne t'était pas destiné ... désolé si tu l'as pris comme celà.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #import "TODO.h"
    
    @implementation Todo
    
    - (id)init
    {
    	if(![super init])
    	return nil ;
    	
    	todoList = [[NSMutableArray alloc] initWithCapacity:10];
    	//[tableTodo setDataSource:self];
    	
    	return self ;
    
    }
    
    
    - (IBAction)addTodo:(id)sender
    {
    	[todoList addObject:[textTodo stringValue]] ;
    	[tableTodo reloadData];
    	
    	
    }
    
    - (IBAction)deleteTodo:(unsigned int)ident
    {
    	[todoList removeObjectAtIndex:ident];
    	[tableTodo reloadData];
    
    }
    
    - (IBAction)doneTodo:(unsigned int)ident
    {
    
    
    }
    
    - (int)numberOfRowsInTableView:(NSTableView *)aTable
    {
    		return ([todoList count]);
    }
           
    - (id)tableView:(NSTableView *)aTable objectValueForColumn:(NSTableColumn *)aCol row:(int)aRow
    {
    		return ([todoList objectAtIndex:aRow]);
    }
    
    - (void)tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
    {
    	[todoList replaceObjectAtIndex:rowIndex withObject:anObject];
    }
    
    @end

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] MySql et Php, première appli
    Par Ganza57 dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 14/03/2013, 09h15
  2. Ma première appli vb
    Par fdthierry dans le forum Windows Forms
    Réponses: 7
    Dernier message: 23/05/2009, 17h40
  3. Première appli simple
    Par House MD dans le forum Flex
    Réponses: 3
    Dernier message: 25/03/2009, 11h26
  4. Première Appli JSF rien ne marche
    Par pure_blue dans le forum JSF
    Réponses: 9
    Dernier message: 01/10/2007, 08h59
  5. Quel lg et IDE pour dev 1 appli multi-plateformes?
    Par Langelot dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 03/02/2005, 23h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo