NSTableView: sortir du mode édition de cellule

RocouRocou Membre
21:03 modifié dans API AppKit #1
Bonjour,

Dans une NSTableView, on peut éditer une cellule en double-cliquant dessus. En cliquant sur une autre cellule, on quitte l'édition.
Je voudrais réaliser cela par programmation mais je n'y arrive pas.

Réponses

  • wiskywisky Membre
    décembre 2009 modifié #2
    Cherche un peu sur les forums, j'ai déjà  posé la même question il y a quelques années.
    En cherchant tu trouvera ;)

    Edit : La preuve : http://www.pommedev.com/forum/index.php?topic=1147.msg12471#msg12471
    :P
  • RocouRocou Membre
    21:03 modifié #3
    dans 1261062535:

    Cherche un peu sur les forums, j'ai déjà  posé la même question il y a quelques années.
    En cherchant tu trouvera ;)

    Edit : La preuve : http://www.pommedev.com/forum/index.php?topic=1147.msg12471#msg12471
    :P

    Oui, je te remercie. J'avais fini par trouver ce fil mais je n'arrive pas a implémenter les exemples.
    Comme pour toi, ça ne passe jamais dans la notification.

    A défaut, est-il possible de rester en édition sur la même ligne en empêchant l'utilisateur de changer de ligne?

    Mon but et de récupérer les valeurs des cellules d'une ligne venant d'être éditée en cliquant sur un bouton de mon interface.
    J'ai trouvé le moyen de sortir de l'édition et de sélectionner la ligne venant d'être éditer en cliquant sur mon bouton mais si l'utilisateur clique (ou double-clique) sur une autre ligne, c'est foutu.
  • wiskywisky Membre
    décembre 2009 modifié #4
    C'est pour cela que la fonction suivante est dans à  implémenter dans l'objet datasource pour recevoir les modifications :
    - (void)tableView:(NSTableView *)aTableView<br />&nbsp;  setObjectValue:(id)anObject<br />&nbsp;  forTableColumn:(NSTableColumn *)aTableColumn<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row:(NSInteger)rowIndex
    

    Cela t'évitera de jouer avec le sélection et une tentative de lecture des données affiché ! NSTableView n'est pas là  pour stocker les données mais uniquement pour les afficher. C'est pour cela qu'après une modification le datasource est averti de la modification.
    Car une fois averti, il modifie les données en mémoire et demande à  la table view de recharger les données (reloadData) !

    EDIT: A tu le livre "Programmation Cocoa sous Mac Os X" ? Si non, je te conseil la section "boutique" de ce site ;)
  • MickMick Membre
    21:03 modifié #5
    Bonjour à  tous,

    J'ai un petit soucis du meme ordre : j'ai une NSTableView alimentée via une dataSource. Un controleur "maison" permet de créer des nouveaux objets (qui sont des NSMutableDictionary) et donc de nouvelles rows. J'aimerais que lorsque la dernière cellule de mon tableau ient de finir d'etre éditée, mon controleur crée un nouvel objet, donc une nouvelle row, et QUE CETTE NOUVELLE Row SOIT EN MODE EDITION. Dans l'état actuel des choses, j'ai subclassé NSTableView et overridé textDidEndEditing:. Pas de problème en ce qui concerne le test dernière ligne et dernière colonne, pas de soucis pour la création de la nouvelle ligne, mais systématiquement, le nouveau "firstResponder" est la première ligne, comme-ci la nouvelle ligne n'existait pas. Il faut donc que l'utilisateur double clique sur la dernière row pour éditer. J'ai essayé les tableColmun selectRow: byExtendingSelection:, puis tableView editColumn: row : withAction: => Au débug, ligne par ligne les choses se passent bien, mais dès que la méthode textDidEndEditing se termine, la focus est donné à  la première ligne !

    Quelqu'un aurait une idée de la stratégie à  adopter ?
  • wiskywisky Membre
    21:03 modifié #6
    Et dans tout cela pense tu à  faire un RealodData pour afficher la nouvelle ligne ?
    Je n'ai jamais eu besoin de ce genre de chose donc j'aurait un peu de mal à  t'aider. Mais tu semble bien parti ;)
  • MickMick Membre
    21:03 modifié #7
    Re-bonjour,

    La méthode add: de mon controleur contient un reloadData. La table est bien à  jour, mais le focus est désespérément à  la première ligne après la méthode textDidEndEditing. Pas moyen de changer le firstResponder.

    Mais peut-etre que je peux accéder à  la nouvelle textFieldCell, mais je ne sais pas comment faire. J'ai bien accès à  la dataCell de la colonne, mais la dataCell n'est pas le textField d'après la doc : il n'y a qu'une dataCell par tableColumn... Comment accéder à  un textField particulier dans une tableView, et lui donner le firstResponder ?? Là  est la question je crois.
  • wiskywisky Membre
    21:03 modifié #8
    J'ai l'impression qu'au moment ou tu est dans le textDidEndEditing la table view n'a pas connaissance de la dernière ligne. Donc, pourquoi ne pas créer la ligne nouvelle lorsque l'utilisateur arrive sur la première colonne de la dernière ligne. Pour connaà®tre le nombre de ligne d'une NSTableView : numberOfRows.
    Pour la dataCell il y en a une par cellule. Mais le modèle est défini une fois dans la colonne. J'espère ne pas dire de bêtise. Il est possible d'accéder à  n'importe quel cellule pour lui donner le firstResponder.
    Pour prendre le contrôle de la préparation des cellules d'une table :
    - (NSCell *)preparedCellAtColumn:(NSInteger)column row:(NSInteger)row
  • MickMick Membre
    21:03 modifié #9
    Re-bonjour
    j'ai effectivement déjà  essayé ta suggestion de créer la nouvelle row avant, qui fonctionne bien. Mais pour le coté "pratique", c'est mieux d'attendre la dernière. Ma table ne sais effectivement pas encore qu'elle a une nouvelle ligne avant l'appel textDidEndEditing.

    Je vais essayer ta méthode - (NSCell *)preparedCellAtColumn:(NSInteger)column row:(NSInteger)row que je ne connaissais pas. A quel objet faut-il envoyer cet appel ?  A la tableView ? je n'ai pas trouvé cette méthode dans la doc...
  • wiskywisky Membre
    21:03 modifié #10
    C'est une méthode qui est à  surcharger. Elle sera automatiquement appelé pour chacune des cellules après un reloadData.
    You can override this method to do any additional cell set up that is required, or invoke it to retrieve a cell that has its contents configured for the specified column and row.

    Par contre il faut Mac OS X 10.5 minimum !
  • RocouRocou Membre
    21:03 modifié #11
    dans 1261132432:

    C'est pour cela que la fonction suivante est dans à  implémenter dans l'objet datasource pour recevoir les modifications :
    - (void)tableView:(NSTableView *)aTableView<br />&nbsp;  setObjectValue:(id)anObject<br />&nbsp;  forTableColumn:(NSTableColumn *)aTableColumn<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row:(NSInteger)rowIndex
    

    Cela t'évitera de jouer avec le sélection et une tentative de lecture des données affiché ! NSTableView n'est pas là  pour stocker les données mais uniquement pour les afficher. C'est pour cela qu'après une modification le datasource est averti de la modification.
    Car une fois averti, il modifie les données en mémoire et demande à  la table view de recharger les données (reloadData) !

    EDIT: A tu le livre "Programmation Cocoa sous Mac Os X" ? Si non, je te conseil la section "boutique" de ce site ;)

    Oui, je sais tout cela. Le problème c'est que quand on est en mode édition, le datasource n'est pas encore mis à  jour!
    Donc, soit je sors du mode édition et je récupère mes données dans mon datasource, soit je récupère ce qui est affiché.

    J'aimerais donc pouvoir sortir du mode édition par programmation (le sujet du fil)  :)
  • wiskywisky Membre
    21:03 modifié #12
    Ok, tu veux sortir par la programmation ! Mais comment détecte-tu que l'utilisateur à  terminer de modifier le contenu ?
    Une solution consisterait à  sous classer la class NSCell que tu utilise pour prendre la main sur la saisie des caractères et ainsi détecter ce que tu souhaite ! Mais sortir du mode d'édition avec le code, je ne vois pas comment faire !
  • Eddy58Eddy58 Membre
    21:03 modifié #13
    Perso je me sers des notifications envoyées quand j'ai besoin de faire des contrôles assez poussés sur les cells d'une tableview :

    Je met le code suivant dans l'initialisation :

    <br />	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(maTableViewTextFieldChange:) name:NSControlTextDidChangeNotification object:maTableView]; // Notification d&#39;édition dans la tableview <br /><br />	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(maTableViewFinEdition:) name:NSControlTextDidEndEditingNotification object:maTableView];	// Notification de fin d&#39;édition dans la tableview<br /><br />	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(maTableViewChangementSelection:) name:NSTableViewSelectionDidChangeNotification object:maTableView]; // Notification de changement de sélection dans la tableview		<br />
    


    Et ensuite on peut récupérer la cell éditée, ou/et effectuer diverses actions :

    <br />-(void)maTableViewTextFieldChange:(NSNotification *)notification<br />{<br />	NSCell *textFieldCell;<br />	<br />	textFieldCell=[maTableView selectedCell];<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; ...etc....<br />}<br />
    

  • mpergandmpergand Membre
    21:03 modifié #14
    dans 1261479133:

    <br />-(void)maTableViewTextFieldChange:(NSNotification *)notification<br />{<br />	NSCell *textFieldCell;<br />	<br />	textFieldCell=[maTableView selectedCell];<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; ...etc....<br />}<br />
    



    selectedCell c'est pour NSMatrix ...

    J'aimerais donc pouvoir sortir du mode édition par programmation (le sujet du fil)


    La méthode la plus simple est:
    [window makeFirstResponder:nil];

    Une autre méthode permet de terminer l'édition même si la saisie est invalide:
    - (void)endEditingFor:(id)anObject (NSWindow)

    En cours d'édition, la valeur est récupérable via le field editor:
    - (NSText *)fieldEditor:(BOOL)createWhenNeeed forObject:(id)anObject (NSWindow)
  • Eddy58Eddy58 Membre
    21:03 modifié #15
    dans 1261487123:

    dans 1261479133:

    <br />-(void)maTableViewTextFieldChange:(NSNotification *)notification<br />{<br />	NSCell *textFieldCell;<br />	<br />	textFieldCell=[maTableView selectedCell];<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; ...etc....<br />}<br />
    



    selectedCell c'est pour NSMatrix ...


    selectedCell est avant tout dans NSControl... Et pour avoir expérimenté ce code crois-moi il fonctionne.


    selectedCell
    Returns the receiver's selected cell.

    - (id)selectedCell

    Return Value
    The selected cell object.

    Discussion
    The default implementation of this method simply returns the control's associated cell (or nil if no cell has been set). Subclasses of NSControl that manage multiple cells (such as NSMatrix and NSForm) must override this method to return the cell selected by the user.

    Availability
    Available in Mac OS X v10.0 and later.


    Ceci dit ta proposition est pas mal non plus, c'est à  essayer :)
  • mpergandmpergand Membre
    21:03 modifié #16
    selectedCell est avant tout dans NSControl... Et pour avoir expérimenté ce code crois-moi il fonctionne.


    Oui mais je comprends pas le concept de selectedCell pour NSTableView ...

    A moins de la faire soi-même :
  • Eddy58Eddy58 Membre
    21:03 modifié #17
    Les cells sont les composantes de bases de ce type de contrôles. Je ne vois pas où est le problème ?
  • AliGatorAliGator Membre, Modérateur
    21:03 modifié #18
    Ca fait longtemps que j'ai pas fait du dev Mac mais on peut, nativement, sélectionner uniquement une cellule dans une NSTableView ?
    Je pense que c'est ça qui questionne mpergand, nativement dans une NSTableView c'est une ligne entière qu'on sélectionne, non ? pas juste une cell ?
  • Eddy58Eddy58 Membre
    décembre 2009 modifié #19
    Ha oui dans ce sens là  en effet, on ne sélectionne que des lignes, ou groupes de lignes ou colonnes. Mais quand on est en mode édition, on peut aller plus loin car on est focalisé sur une seule cell, et celle-ci est récupérable via selectedCell. On peut également forcer une cell à  se mettre en mode édition avec la méthode editColumn:row:withEvent:select:.

    EDIT : En utilisant la dernière méthode citée ci-dessus on peut sortir du mode édition comme ceci :
    <br />[maTableView editColumn:-1 row:-1 withEvent:nil select:NO];	<br />
    



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