Ajouter une row et mettre à jour firstResponder
Mick
Membre
Bonjour à tous,
Je me permets de relancer un nouveau sujet sur les problèmes de firstResponder dans une tableView.
J'ai une NSTableView gérée par une dataSource. Pas de soucis sur le fonctionnement. Une méthode add: d'un controleur permet d'ajouter un objet, qui par voie de conséquence entraine l'ajout d'une row => Dans la méthode add, j'ai donc un reloadData.
Le soucis est le suivant : je souhaite que lorsque l'utilisateur a terminé d'éditer la dernière cell de la tableView, la méthode add: soit appelée, afin de créer une nouvelle row, et que les nouvelles cellules soient les nouveaux responder (si l'utilisateur a appuyé sur entrée, la cellule active doit etre celle en-dessous de celle qu'il éditait, et si il a appuyé sur tab, c'est celle de la première colonne qui est active en édition). Logiquement, j'ai donc overridé la méthode textDidEndEditing, dans laquelle je teste si c'est bien la dernière cellule. Pas de soucis, mon nouvel objet est bien créé et entraine bien une nouvelle row, Mais l'édition est donnée à la première ligne. J'ai tenté un selectRow, puis un editColumn: row: => Au débug, ligne par ligne ça colle, jusqu'à la fin de la méthode textDidEndEditing => Le focus est donné à la première row juste après avoir été donné à la bonne !! C'est lorsque la méthode textDidEndEditing est terminée qu'il se passe un truc qui redonne le focus à la 1ere row. I don't understand what happens !!
Quand j'essaye un makeFirstReponder, message d'erreur . J'essaye de donner le responder de la façon suivante :
M'y prends-je correctement ? Dans la doc d'Apple j'ai compris qu'il n'y avait qu'un dataCell... Comment accéder au textFieldCell's ?
Je me permets de relancer un nouveau sujet sur les problèmes de firstResponder dans une tableView.
J'ai une NSTableView gérée par une dataSource. Pas de soucis sur le fonctionnement. Une méthode add: d'un controleur permet d'ajouter un objet, qui par voie de conséquence entraine l'ajout d'une row => Dans la méthode add, j'ai donc un reloadData.
Le soucis est le suivant : je souhaite que lorsque l'utilisateur a terminé d'éditer la dernière cell de la tableView, la méthode add: soit appelée, afin de créer une nouvelle row, et que les nouvelles cellules soient les nouveaux responder (si l'utilisateur a appuyé sur entrée, la cellule active doit etre celle en-dessous de celle qu'il éditait, et si il a appuyé sur tab, c'est celle de la première colonne qui est active en édition). Logiquement, j'ai donc overridé la méthode textDidEndEditing, dans laquelle je teste si c'est bien la dernière cellule. Pas de soucis, mon nouvel objet est bien créé et entraine bien une nouvelle row, Mais l'édition est donnée à la première ligne. J'ai tenté un selectRow, puis un editColumn: row: => Au débug, ligne par ligne ça colle, jusqu'à la fin de la méthode textDidEndEditing => Le focus est donné à la première row juste après avoir été donné à la bonne !! C'est lorsque la méthode textDidEndEditing est terminée qu'il se passe un truc qui redonne le focus à la 1ere row. I don't understand what happens !!
Quand j'essaye un makeFirstReponder, message d'erreur . J'essaye de donner le responder de la façon suivante :
<br />[[self window] makeFirstResponder:[laColonne dataCellForRow:laRow]];<br />
M'y prends-je correctement ? Dans la doc d'Apple j'ai compris qu'il n'y avait qu'un dataCell... Comment accéder au textFieldCell's ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Après la sortie de la méthode textDidEndEditing, la cellule que je force à éditer avec editColumn: row: withEvent: select: perd le focus !!
Au débug, ligne par ligne cela se voit : elle a le focus, puis le perd juste après...
Au débug c'est dans quelle méthode que ça zappe ?
Et si t'envoyais une notification à ton contrôleur qui la récupère juste après, et lance alors l'édition de la bonne colonne/ligne ?
Justement, je ne vois pas ce qui cloche.
La structure du projet : j'ai un controleur (subclass de NSObject) qui gère l'ajout et la suppression des objets associés à une row. Il y a donc une méthode add: dans ce controleur qui est donc appelée par la méthode textDidEndEditing si la editedColumn: et la editedRow sont les dernières.
Après l'appel, je force la sélection de cette dernière row, puis l'édition avec editColumn: row: withAction: select:
Et ensuite, la méthode textDidEndEditing se termine, et c'est le drame... (je n'appelle aucune autre méthode....)
J'avoue ne pas trop utiliser ces notifications. Il va falloir que je me penche dessus. Si ClicCool tu as un exemple je suis preneur.
http://forums.macgeneration.com/5322483-post4.html
Une façon un peu bidouille de se sortir de ce genre de problème, c'est de faire un performSelectorAfterDelay.
Oui,
Je préfère quand même la voie de la Notification qui sera exécuté immédiatement à la sortie du runLoop (à l'entrée dans le loop suivant au moment de la lecture des évènements en attente si j'ai bien saisi leur fonctionnement) l'ayant envoyée
NSNotification c'est le pattern "Observer" (ou "Listener"), et normalement dans ce pattern dès que tu envoies une notification (postNotificationName:...) et que le NSNotificationCenter la reçoit, elle sort de son chapeau le NSArray d'Observers associés à cette notification, et appelle la méthode qui va bien sur ces objets... directement.
En fait, dans la méthode didEndEditing, le"did" ne veut pas tout-à -fait dire "did"... Comprenne qui voudra !
à‰tonnant en effet ! Il doit y avoir une valeur qui n'est pas mise à jour !
Pour ma part, le fait que la ligne soit absente de la table avant l'appel de textDidEndEditing est source de problème. Mac OS X doit vérifier la valeur countRow et voyant qu'il est à la dernière il retourne à la première ligne.
A priori non puisqu'initialement ça marche.
C'est en sortant du [tt]textDidEndEditing[/tt] que le focus change sans crier gare.
J'ai résolu mon problèle en modifiant le setObject: de la dataSource, mais par curiosité j'aimerais essayer de changer le nextResponder dans la méthode textDidEndEditing pour voir. Le soucis est d'avoir accès au textFieldCell fraichement créé : how can I do ?
D'après la doc, une tableColumn a un dataCell et un headerCell. => Comment accéder au textFieldCell's, afin d'envoyer le message
On pourrait essayer de voir du coté de dataCell:
Sauf que la valeur des cells est inexploitable en dehors des méthodes concues à cet effet (willDisplayCell, etc)
Par contre le field editor semble plus intéressant:
La valeur est correcte, ceci dit, je vois pas ce que tu pourrais faire à partir de ça pour résoudre ton problème ...
Je pense pas qu'il soit possible de faire quelque chose puisque le reloadData est ignoré par tableView à ce niveau.
La seule solution c'est d'intercepter les tab au niveau de keyDown et de gérer soi-même l'édition des cellules.
Good luck
Par contre, dans quels cas serait-il judicieux d'overrider textDidEndEditing ? Quelqu'un a des exemples ? (peut-etre cela peut me servir un jour)
Je l'ai fait pour sortir de l'édition mais rester sur la ligne sélectionnée !
Une méthode plus propre serait d'intercepter doCommandBySelector.
Dans une sous classe de NSTableView ajouter:
Ca gère les tabs et backtabs.
Une nouvelle méthode delegate "tableViewWillEditNextCell:" est appelé lors d'un tab.
C'est donc dans cette méthode qu'il faut tester si la cellule en édition est la dernière et agir en conséquence. (addRow reloadData etc)
Pour éviter le warning sur la nouvelle méthode, on peut définir un protocole, ou faire un simple performSelectorWithObject.
Bien vu. Mpergand où as-tu trouvé cette méthode textView doCommandBySelector dans la doc ?