NSComboBox et uncompletedstring

chaps31chaps31 Membre
14:52 modifié dans API AppKit #1
Bonjour à  tous,

Mon problème est simple je voudrais créer une combobox qui complète ce que tape l'utilisateur en fonction de son Datasource.

Première utilisation des ComboBox, j'ai implémenté le protocole Datasource ComboBox , impec la liste se remplie. par contre s'il y a par exemple "gorgonne" dans la liste je voudrais que la ComboBox se remplisse automatiquement avec "gorgone" si ce que tape l'utilisateur commence par "gor..."

Ma (première) question, il me semblait avoir compris qu'il suffisait d'implémenter :

comboBox:completedstring et  comboBox:indexOfItemWithStringValue, mais ça ne fonctionne pas... Est-ce parce-que ce ne sont pas les bonnes méthodes ou bien est-ce les bonnes méthodes et il faut revoir mon code (et il y aura alors certainement une 2eme question...)?
Parceque le truc c'est que je met des NSLog pour vérifier ce qui se passe et là  rien n'apparait, si je tape du texte dans la ComboBox visiblement les méthodes ci-dessus ne sont pas exécutées...  :crackboom:-

Merci par avance de vos lumières...

Réponses

  • Philippe49Philippe49 Membre
    14:52 modifié #2
    Tu as coché correctement dans les attributs de ton ComboBox ?
  • Philippe49Philippe49 Membre
    juin 2008 modifié #3
    Comme cela ça marche :

    -(void) awakeFromNib
    {
    comboItems=[[NSArray alloc] initWithObjects: @Gorgonne,@Zola,@Parme,@Zan,nil];
    }
    [EDIT] : c'est mieux si on met cette initialisation dans la méthode -(id) init

    #pragma mark Combo Datasource
    - (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
    {
    return [comboItems count];
    }
    - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index
    {
    return [comboItems objectAtIndex:index];
    }

    [EDIT] optionnel
    - (NSString *)comboBox:(NSComboBox *)aComboBox completedString:(NSString *)uncompletedString
    {
    NSInteger index=0;
    unichar c0=[uncompletedString characterAtIndex:0];
    if(c0=='P' || c0=='p'){
    index=2;
    }else if(c0=='Z' || c0=='z'){
    unichar c1=[uncompletedString length]>1 ? [uncompletedString characterAtIndex:1]:'o';
    index=(c1=='O'||c1=='o')? 1:3;
    }
    return [comboItems objectAtIndex:index];
    }

    [EDIT] optionnel
    - (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)aString
    {
    [EDIT] Plus simplement : return [comboItems indexOfObject:aString];
    NSUInteger index=0;
    while( index<[comboItems count]){
    if( [aString isEqualToString:[comboItems objectAtIndex:index] ]) return index;
    index++;
    }
    return NSNotFound;
    }

  • chaps31chaps31 Membre
    14:52 modifié #4
    Merci, je vais comparer ça avec mon code
  • AliGatorAliGator Membre, Modérateur
    14:52 modifié #5
    En tout cas moi j'adore ton contenu d'exemple, Philippe49 ;D
  • chaps31chaps31 Membre
    14:52 modifié #6
    Pourquoi un while dans :
    - (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)aString
  • Philippe49Philippe49 Membre
    14:52 modifié #7
    dans 1212803268:

    En tout cas moi j'adore ton contenu d'exemple, Philippe49 ;D

    Avec un petit Chianti, ... y a pas de mal !

    (J'ai un peu amélioré le code ci-dessus, notamment le indexOfItemWithStringValue est nécessaire au bon fonctionnement du Combo)

    dans 1212824217:

    Pourquoi un while dans :
    - (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)aString


    La méthode indexOfObject: devrait marcher aussi sous réserve qu'il y n'ait pas de copie bizarre entre l'interface et le code.
  • chaps31chaps31 Membre
    14:52 modifié #8
    Marche pas  :'(
    Le plus étrange c'est que je me disais que lorsque je tapais quelque chose dasn la comboBox normalement la méthode - (NSString *)comboBox:(NSComboBox *)aComboBox completedString:(NSString *)uncompletedString - devrait être appelée, j'ai mis un NSLog dans cette méthode, et rien n'apparait dasn le RunLog donc, la méthode n'est pas appelé... J'ai zappé un truc dasn le protocole ????

    PS Philippe49 le fromage, AliGator le Chianti, j'amène le pain  :)
  • Philippe49Philippe49 Membre
    14:52 modifié #9
    Tu es certain d'avoir correctement fait les connections dans IB ?


    dans 1212825068:

    PS Philippe49 le fromage, AliGator le Chianti, j'amène le pain  :)

    Euh si tu connais quelques Italiennes, le p'tit déj pourrait être sympa ...  :o ::)
  • chaps31chaps31 Membre
    14:52 modifié #10
    Hum... léger oubli... :o   le "completed" dans IB... Merci de ton secours, même si je me sens un peu Boulet là ...
    CA MARCHE
  • AliGatorAliGator Membre, Modérateur
    14:52 modifié #11
    Ah ben du coup je te laisse payer ton coup en amenant leChianti alors  ;) :p
  • Philippe49Philippe49 Membre
    juin 2008 modifié #12
    dans 1212827090:

    CA MARCHE

    En fait, ça marche même si on n'implémente pas la méthode comboBox:completedString:



    Doc Apple
    comboBox:completedString: returns a string that begins with the specified string. If autocompletion is enabled, the combo box tries to complete what the user enters into the text field with an item from the pop-up list. If this method isn't available and autocompletion is enabled, the combo box goes through each item one-by-one to find a completion.
  • chaps31chaps31 Membre
    14:52 modifié #13
    dans 1212836455:

    dans 1212827090:

    CA MARCHE

    En fait, ça marche même si on n'implémente pas la méthode comboBox:completedString:



    Doc Apple
    comboBox:completedString: returns a string that begins with the specified string. If autocompletion is enabled, the combo box tries to complete what the user enters into the text field with an item from the pop-up list. If this method isn't available and autocompletion is enabled, the combo box goes through each item one-by-one to find a completion.



    Bigre... mais tu as raison, enfn Apple a raison... Bref vous avez raison... du coup les méthodes facultative ne servent qu'avec une autocompletion non présente dasn la liste... un peu étrange mais bon.
  • chaps31chaps31 Membre
    14:52 modifié #14
    Toujours un problème. Tout fonctionne impec, sauf que visiblement le datasource du combobox est chargé uniquement lorsque l'on clique sur le menu déroulant de la combobox.

    Si je déroule la liste puis tape qque chose, ok, ça se rempli automatiquement, mais si je ne déroule pas la liste et que je tape directement (ce qui est fait habituellement) la pas de remplissage automatique... Je déroule le menu et retap, plus de pb remplissage...

    Comment faire pour que le datasource soit appelé à  la sélection de la combobox et non pas uniquement lors du déroulement du menu?
  • Philippe49Philippe49 Membre
    14:52 modifié #15
    Essaie la méthode
    reloadData
    Marks the receiver as needing redisplay, so that it will reload the data for visible pop-up items and draw the new values.
    - (void)reloadData

    après l'initialisation de manière à  forcer la lecture des données une première fois, ou tout autre méthode du même tonneau.
  • chaps31chaps31 Membre
    14:52 modifié #16
    Mais où le mettre le reloaddata, pusique le problème est que la combobox n'appelle pas ses protocoles datasource lorsque l'on tape ...
  • Philippe49Philippe49 Membre
    14:52 modifié #17
    Curieux en effet, si on met dans awakeFromNib :
    if([comboBox completes]) NSLog(@completes);
    else NSLog(@does not complete);

    le log donne "does not complete"

    Par contre si on met
    -(id) init {
    self=[super init];
    if(self){
              comboItems=[[NSArray alloc] initWithObjects: @Gorgonne,@Zola,@Parme,@Zan,nil];
            }
    return self;
    }

    Alors cela marche.
    Il y a un problème de synchronisation.
  • Philippe49Philippe49 Membre
    14:52 modifié #18
    Autre solution

    -(void) awakeFromNib
    {
    comboItems=[[NSArray alloc] initWithObjects: @Gorgonne,@Zola,@Parme,@Zan,nil];
    [comboBox setCompletes:YES];
    }


  • chaps31chaps31 Membre
    14:52 modifié #19
    Une question, lorsque l'on fait un reloadData que se passe-t'il ?

    Le receveur lance tous les protocoles de son accès datasource ?
  • Philippe49Philippe49 Membre
    14:52 modifié #20

    La Doc :
    And here are some NSComboBox methods your data source may need if it loads data in the background:

    noteNumberOfItemsChanged informs the combo box that the number of items in the data source has changed.
    reloadData marks the combo box as needing redisplay, so it reloads the data for the visible pop-up items and draws the new values.


    Ainsi un changement des données peut se faire ainsi, les deux méthodes n'étant pas forcément nécessaires : 
    -(IBAction) changeItems:(id) sender
    {
    [comboItems release];
    comboItems=[[NSArray alloc] initWithObjects: @Gri,@Zouk,@Paris,@Zaza,@prix,nil];
    [comboBox noteNumberOfItemsChanged]; // optionnel
    [comboBox reloadData];  // optionnel
    }


    Sans avoir essayer, il est probable que le reloadData ne doit être véritablement nécessaire que lors d'une implémentation plus poussée : une sous-classe pour les items par exemple avec un NSFormatter, ou sous-classe pour la NSComboBoxCell, ...

    dans 1213435323:

    Le receveur lance tous les protocoles de son accès datasource ?

    Je ne pense pas, l'interface graphique a un comportement "paresseux". Elle ne demande les données que si elle en a besoin.

  • chaps31chaps31 Membre
    14:52 modifié #21
    Merci tout march...ait... sauf que nouveau problème....

    La liste de la comboBox2 dépend de la valeur de la comboBox 1, ce qui fonctionne très bien, mais si je modifie la combobox 1 je ne trouve aucun moyen de faire une mise à  jour de la liste de la 2. Donc avec un IBAction ça ne marche pas... Il faudrait que lorsque je sélectionne la combobox 2, hop elle met à  jour sa liste en fonction de la comboBox 1, pour cela il suffit qu'elle relance son protocole datasource ce qui se fait sans problème avec un : [combobox2 noteNumberOfItemsChanged];

    Sinon avec un combobox 1 non modifié ça marche très bien (enfin) pas besoin de dérouler le menu je commence à  taper et hop ça se rempli automatiquement.

    Merci par avance.

    PS : je suis passé voir un caviste aujourd'hui.. :P
  • Philippe49Philippe49 Membre
    14:52 modifié #22
    Il n'y a aucune raison de mettre à  jour les données puisque les données utilisées par les comboBox sont en dur les NSArray du datasource. Le protocole datasource en lui-même ne met rien à  jour, il se contente de demander ce qu'il faut afficher.
    Ce n'est donc que lors d'un nouvel affichage que les méthodes sont appelées.

  • Philippe49Philippe49 Membre
    14:52 modifié #23
    dans 1213466746:

    La liste de la comboBox2 dépend de la valeur de la comboBox 1, ce qui fonctionne très bien, mais si je modifie la combobox 1 ...

    Si tu changes un contenu d'un combo box, il doit falloir utiliser les méthodes du delegate soit les méthodes décrites dans NSComboBox, soit celles décrites dans NSTextField (NSComboBox hérite de NSTextField).
    Etant informé d'un changement par notification, le delegate->datasource fait les transformations nécessaires dans la NSArray model.

    dans 1213466746:

    PS : je suis passé voir un caviste aujourd'hui.. :P

    Ben y a intérêt !!
  • chaps31chaps31 Membre
    14:52 modifié #24
    Impec Merci 
Connectez-vous ou Inscrivez-vous pour répondre.