Number Formater et Notifications
Mulot
Membre
Voilà , un petit soucis et je ne sais pas trop comment l'aborder :
J'ai un NSTextField qui se voit adjoindre un NSFormater, celui pour rentrer des sommes monaitaires. Jusque là tout marche impeccablement bien, mais je veux modifier le comportement de ma GUI, et notamment d'un bouton, qui ne doit être activé que si ce textField avec formatter (et un autre TextField "normalé) contiennent des valeurs non nulles.
Je me dis, c'est le moment d'utiliser les notifications, et notamment NSControlTextDidChangeNotification, j'ajoute mon controller au notification center, lui donne une méthode pour updater les boutons en question.
J'implémente la méthode qui sera appelée pour toute notification reçue (elle se charge de vérifier le contenu des deux textfield et de ou non rendre le boutton actif).
Je teste mon application, je peux saisir ce que je veux dans le textfield sans formateur, dans le second en revanche, si je tape "d'une traite", une valeur, il ne va prendre que le premier chiffre, par exemple si je tape 1342, je vais obtenir $ 1,00. Si je suis "au bout" de ma valeur du textfield, et que je fais retour, le valeur ne disparaà®t pas, je suis obligé de positionner le curseur là ou je veux insérer de nouveaux nombres pour que cela fonctionne.
Autre fait troublant, une fois que j'obtient cette valeur de 1,00 (si j'avais tapé quelque chiffre commencant par 1), je peux incrémenter de 1 en 1 les centimes, en appuyant sur une touche supérieure ou égale à 5 !
Si j'enlève l'objet observateur du centre de notification, le formateur marche très bien, quelle est donc la solution ? Est-ce que la notification intervient sur le comportement du formateur ? Faut dire surcharger une quelconque méthode ?
J'ai un NSTextField qui se voit adjoindre un NSFormater, celui pour rentrer des sommes monaitaires. Jusque là tout marche impeccablement bien, mais je veux modifier le comportement de ma GUI, et notamment d'un bouton, qui ne doit être activé que si ce textField avec formatter (et un autre TextField "normalé) contiennent des valeurs non nulles.
Je me dis, c'est le moment d'utiliser les notifications, et notamment NSControlTextDidChangeNotification, j'ajoute mon controller au notification center, lui donne une méthode pour updater les boutons en question.
J'implémente la méthode qui sera appelée pour toute notification reçue (elle se charge de vérifier le contenu des deux textfield et de ou non rendre le boutton actif).
Je teste mon application, je peux saisir ce que je veux dans le textfield sans formateur, dans le second en revanche, si je tape "d'une traite", une valeur, il ne va prendre que le premier chiffre, par exemple si je tape 1342, je vais obtenir $ 1,00. Si je suis "au bout" de ma valeur du textfield, et que je fais retour, le valeur ne disparaà®t pas, je suis obligé de positionner le curseur là ou je veux insérer de nouveaux nombres pour que cela fonctionne.
Autre fait troublant, une fois que j'obtient cette valeur de 1,00 (si j'avais tapé quelque chiffre commencant par 1), je peux incrémenter de 1 en 1 les centimes, en appuyant sur une touche supérieure ou égale à 5 !
Si j'enlève l'objet observateur du centre de notification, le formateur marche très bien, quelle est donc la solution ? Est-ce que la notification intervient sur le comportement du formateur ? Faut dire surcharger une quelconque méthode ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Dans mon init de mon controller :
Et la méthode UpdateUIButtons:
Je pense que le soucis vient du Formater puisque quand je le supprime, aucun soucis, et idem pour deux autres champs (sans formateurs) et un autre bouton.
J'ai essayé tout les formats possibles pour le formater, rien n'y fait, il ne veut prendre qu'un seul chiffre, et je suis obligé d'utiliser les flèches directionnelles pour insérer éventuellement des chiffres, assez étrange.
Par contre le comportement est plutôt windosien, une fois mes deux textfields remplis, il faut sélectionner ou cliquer sur un autre composant atomique pour que la notification soit émise et que le bouton soit activé. Alors que le comportement de NSControlTextDidChangeNotification me permet encore de saisir du texte une fois le bouton activé, afin de bien montrer à l'utilisateur que les champs sont requis.
Il faudrait que je trouve pourquoi le formatter se "bloque" alors que le textfield envoie les notifications. Une petite idée sur la marche à suivre ? Sous classer NSTextField et ajouter des NSLog dans les méthodes susceptibles d'être appelées voir ou le problème se produit ?
Il existe plusieurs options dont setMaximumFractionDigits: déterminant le nombre de décimales (après virgule) autorisées.
Je ne sais pas comment tu as créé ce formatter (dans IB ou par prog), mais revoie sa config.
.
Je vais essayer me tripatouiller avec lui !
Lorsque je veux que les notifications soient envoyées à la fin de l'édition, tout marche comme il faut, le formatter joue son rôle (faudra que j'améliore l'affichage mais bon, détail).
Par contre, lorsque je teste avec les notifications à chaque fois que c'est édité, rebelotte, il ne prend en compte que le premier chiffre, même comportement qu'avec celui de IB. Là y'a quand même un soucis, qui doit venir de la notification, ou du comportement du formatter vis à vis de la notification non ?
Que puis-je essayer d'autre pour résoudre se problème, il me fat vraiment ce formatter ainsi que la notification NSControlTextDidChangeNotification, pour que cette partie soit cohérente pour l'utilisateur.
Merci !
En fait, dans ta notif, le fait de lire (par un [operationAmountField doubleValue]) ton textField fait que le formatter attaché entre en action immédiatement (afin que doubleValue te retourne la valeur formatée).
C'est ce qui provoque cet effet de bord...
Pour éviter cela, remplace le bloc
par
Dans ce cas, tu n'interroges pas le textField directement (donc pas de formatage inopiné), mais son fieldEditor (objet qui est responsable de la saisie/affichage de texte) sous-jacent.
.
Je suis vraiment désolé de poster un message inutile dans ce topic, mais j'ai vraiment besoin de savoir.
Dans ton avatar, fouf, c'est une fraise ou un carrotte?
Je ne pouvais pas m'en empècher :P ... bon je sors :fouf): :(renaud):
Si j'essaie d'interpréter le bout de code que m'a donné, en gros je récupère la valeur de mon textField en utilisant les méthodes de super classe afin de ne pas les demander "directement" au TextField, ce qui provoque le soucis du formatter, est-ce que c'est n peu près ça ?
EDITH: après lecture de la fin de ton post (précipitation !), je me rend compte que tu as pensé à tout !
Par contre pour ce qui est du code à modifier, on utilise des méthodes des super classes, mais je ne comprend pas trop la notion de "window field editor".
Ce window field editor contient toutes les données saisies dans des composants appartenant à la fenêtre du composant sur lequel on a appellé la méthode window ?
Surtout que dans mon cas j'ai de multiples NSTextField, comment le window field editor peut ne s'occuper que de mon champs ? Parce que aucune référence n'est faite par la suite sur le champs voulu. Moi j'aurais plutôt pensé mettre operationAmountField en paramètre de la méthode " fieldEditor:forObject: ".
Autre petite question, textStorage n'existe apparemment pas en tant que tel, et j'ai deux possibilités :
- [myText textStorageDidProcessEditing:<#(NSNotification *)notification#>
ou bien
- [myText textStorageWillProcessEditing:<#(NSNotification *)notification#>
Et là je ne vois pas trop quoi faire, que ça soit pour la gestion de la notification ou laquelle de ces deux méthodes utiliser.
EDITH BIS:
@Elf : "Penser à ne pas aller manger chez toi *note dans iCal*"
Donc je vais te conter la belle histoire des textField, textView et autres joyeusetés dans le monde chocolaté...
Il était une fois...
NSTextField est une classe permettant d'afficher un texte à l'écran.
Cette classe dérive de NSView, et elle contient un NSTextFieldCell, classe chargée de l'affichage à l'écran du texte.
Mais, lorsque NSTextField devient éditable (donc quand le focus est dessus, avec le point d'insertion actif), le NSTextFieldCell "disparaà®t" au profit d'un autre objet, un NSTextView. La classe NSTextView est le pivot de tout ce qui est édition de texte sous cocoa. Enfin, quand l'édition du texte est terminée, NSTextView disparaà®t pour laisser à nouveau la place au NSTextFieldCell.
Cependant, pour des raisons de coût (en performance et en empreinte mémoire), il n'existe qu'un seul NSTextView par fenêtre. Il est partagé par tous les NSTextField qui sont éditables.
On accède à l'instance de NSTextView de la fenêtre via la méthode fieldEditor:forObject:.
Le NSTextView communique avec son NSTextField en cours d'édition, donc toutes les notifications de NSTextField sont toujours valables, même si c'est NSTextView qui est en cours d'utilisation.
Donc, tu peux lire le contenu d'un textField soit par les méthodes stringValue et consorts, soit en accédant au NSTextView quand le textField est en cours d'édition.
L'avantage de la seconde méthode est de ne pas provoquer la validation du formatter attaché au textField.
Donc, ton code devrait ressembler à çà :
et
.
Par contre une petite question question vis à vis des notifications, ma méthode updateUIButtons prend maintenant en paramètre une notification, quand j'ai ajouté au controller l'objet observer au Notification Center, j'ai juste précisé @selector(updateUIButtons[.b].
Est que le centre de notification renvoi automatiquement la notification reçue comme paramètre de la méthode à appeler ?
D'après la doc Apple (voir ici), la méthode exécutée par le notificationCenter doit avoir un argument.
L'argument est la notification qui a été postée par l'objet observé.
Dans ton cas, c'est utile pour récupérer l'id de l'objet (méthode object de NSNotification) qui a émis la notif : en d'autre terme, cela permet de distinguer quel textField est en cours d'édition pour y appliquer la méthode du fieldEditor au lieu de la méthode du stringValue pour savoir si il est vide ou non.
.
Je commence peut à peu à m'imprégner du monde de Cocoa, et à voir la "philosophie" de celui-ci.