[Rà‰SOLU]Fonctionnement du délégué "controlTextDidChange"

epetit91epetit91 Membre
février 2012 modifié dans Objective-C, Swift, C, C++ #1
Bonsoir,



Quelqu'un peint-il m'expliquer pourquoi la chose suivante fonctionne :



Dans Interface Builder, j'ai défini un "NSPanel" avec un champ "NSTextField" dans lequel je souhaite ne saisir que des chiffres avec une valeur maxi à  999999.

J'ai glissé sur ce champ un "Number Formatter" avec les paramètres suivants :

- Style : None

- Maximum : 999999

- Localize : activé



J'ai enfin fait un lien entre le "delegate" de mon champ de saisie et le "File's Owner" dans lequel se trouve mon panel.



Dans xCode, j'ai défini une classe de type NSPanel dans laquelle j'ai défini le délégué suivant :
<br />
- (void)controlTextDidChange:(NSNotification *)notification<br />
{<br />
	[txtChampNumero stringValue];<br />
}<br />




Lorsque je compile tout cela et que je lance le programme tout fonctionne à  merveille à  savoir :
  1. Si je saisis des chiffres et que la valeur du champ est supérieur à  999999, le champ s'efface.
  2. Lorsque le champ est vide et que je saisis un caractère autre qu'un caractère numérique, rien ne s'affiche.
  3. Si au cours de la saisie de chiffres je saisis un caractère non numérique, le champs s'efface.




Ce fonctionnement me convient bien mais je ne comprends pas son fonctionnement.

Que fait le délégué avec le code que j'y ai entré ?

Bien évidemment, si je le supprime, plus aucun filtrage n'est réalisé et je peux saisir n'importe quoi.



Quelqu'un a-t-il une explication à  me donner car je ne peux pas rester sans comprendre ?



D'autre part, je souhaiterai améliorer le point 3 de manière à  ce que le champ ne s'efface pas si je saisis un caractère non numérique au milieu de caractères numériques et que ce caractère non numérique ne soit pas pris en compte comme au point 2.



Avez-vous une idée de ce qu'il faut faire ?



Avec mes sincères remerciements.

Réponses

  • Je pense avoir compris le fonctionnement de ce qui se passe.

    Sans la méthode déléguée, la validation de la saisie se fait pas appui sur la touche Entrée.

    Le fait dans le délégué de recopier le contenu du champ de saisie équivaut à  valider une saisie ce qui déclenche les contrôles du formatteur (valeur max et caractère non alphabétique).



    Mon analyse est-elle correcte ?

    Merci
  • CéroceCéroce Membre, Modérateur
    En l'état, tu pourrais supprimer la méthode déléguée que ça ne changerait rien au comportement: en effet, elle se contente d'informer le délégué que le contenu du champ a changé. -stringValue renvoie le contenu du champs sous forme de NSString; comme tu ne stockes pas le contenu dans une variable, cet appel de méthode ne sert à  rien.



    C'est donc le NSNumberFormatter qui fait tout le travail. J'ignore si le number formatter corrige l'entrée avant que la méthode déléguée soit appelée ou le contraire.
  • Merci pour ton commentaire.

    Si je supprime le délégué j'ai le comportement décrit dans mon message de départ à  savoir que l'on peut saisir n'importe quoi et c'est à  la validation par appui sur entrée que l'on est averti par un Beep que la saisie est incorrecte tout en laissant le contenu du champ inchangé.

    Avec la méthode délégué, le comportement est conforme à  ce que j'attends (pas de prise en compte des caractères alphabétiques et limitation de la saisie des nombres à  la valeur définie dans le formatter).

    Certe je ne stocke pas le contenu dans une variable mais le fait de recopier le contenu du champ dans lui même provoque le comportement attendu.

    Merci.
  • CéroceCéroce Membre, Modérateur
    Effectivement dans la description de -[NSControl stringValue], il est dit que -[validateEditing] est appelée (la validation est forcée).

    Comme quoi, on en apprend tous les jours.
  • epetit91epetit91 Membre
    février 2012 modifié #6
    Bonsoir,



    Voici comment j'ai résolu mon problème d'effacement du contenu du champ de saisie lorsque je saisis un caractère non numérique après un caractère numérique (point 3 de mon post initial) :


    <br />
    - (void)controlTextDidChange:(NSNotification *)notification<br />
    {<br />
        NSString    *valeur = [txtChampNumero stringValue];<br />
    <br />
        //  Le dernier caractère saisi est un chiffre : renvoie la valeur dans le champ<br />
    <br />
        if ([valeur characterAtIndex: [valeur length]-1] &gt;= &#39;0&#39; &amp;amp;&amp;amp; [valeur characterAtIndex: [valeur length]-1] &lt;= &#39;9&#39;)<br />
    	    [txtChampNumero stringValue];<br />
    <br />
        //  Le dernier caractère saisi est une lettre<br />
        else<br />
        {<br />
    	    //  Si le champ n&#39;est pas vide<br />
    	    //  Permet d&#39;éviter une exception si après avoir saisi un caractère numérique on appui sur la touche &quot;Retour arrière&quot;<br />
    <br />
    	    if ([valeur length] &#33;= 0)<br />
    	    {<br />
    		    //  Récupération des (n-1) caractères de la chaà®ne et renvoi dans le champ<br />
    		    //  Nota : le texte du champ se trouve alors sélectionné<br />
    <br />
    		    [txtChampNumero setStringValue:[valeur substringToIndex:[valeur length]-1]];<br />
    		   <br />
    		    //  Désectionne le texte du champ en positionnant le curseur à  la fin du texte<br />
    <br />
    		    [[txtChampNumero currentEditor] setSelectedRange: NSMakeRange([valeur length]-1, 0)];<br />
    	    }<br />
        }<br />
    }<br />
    




    Parallèlement à  cela, un "Number Formatter" teste les limites de la valeur numérique saisie.

    Je ne sais pas si il y a plus simple, mais cela fonctionne et répond parfaitement à  mon besoin.

    Si cela peut aider quelqu'un.



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