[Résolu] Valeur bindée mais initialement non synchronisée

IlluminatiIlluminati Membre
mars 2008 modifié dans API AppKit #1
Bonjour à  tous,

C'est mon premier post sur ce forum : je suis débutant dans le monde du développement Mac et je fais mes premiers pas en Objective-C avec Cocoa. Et donc forcément, ça ne marche pas du premier coup  ::).

Mon problème est relativement simple. J'ai construit une petite application qui affiche une carte maison MapView (une sorte de damier) et possède une barre d'outils avec un NSSlider et un NSTextField. Le NSSlider et le NSTextField sont tous deux bindés sur un contrôleur MapViewController, maison lui aussi, et lui même connecté (via une IBOutlet) sur la carte pour faire le lien entre la valeur bindée et l'échelle de la carte.

L'ensemble fonctionne correctement a un détail près : les valeurs de départ du NSSlider et du NSTextField sont des valeurs par défaut différentes de celle de l'échelle de la carte. Si on utilise l'un ou l'autre des controls, le binding opère et tout se synchronise correctement, c'est juste au démarrage que ça coince.

Est-ce un fonctionnement normal ? Et comment y porter remède ?

A toute fin utile, voici le code du contrôleur :
<br />@interface MapViewController : NSObject {<br />	IBOutlet MapView * mapView;<br />}<br /><br />- (IBAction)setScale:(id)sender;<br />- (CGFloat)scale;<br /><br />@end<br /><br />@implementation MapViewController<br /><br />- (IBAction)setScale:(id)sender {<br />	// Pratique : NSSlider et NSTextField répondent tous deux à  ce message.<br />	CGFloat scale = [sender intValue];<br />	[mapView setScale:scale];<br />}<br /><br />- (CGFloat)scale {<br />	return [mapView scale];<br />}<br /><br />@end<br />

Réponses

  • Philippe49Philippe49 Membre
    mars 2008 modifié #2
    Le panel du binding présente une option "PlaceHolder" qui permet de préciser la valeur prise en l'absence de mise à  jour, en particulier au démarrage.
    La seconde solution serait dans la méthode
    -(void) awakeFromNib
    {
        [self setScale: ...];
    }

    Ceci dit ta méthode setScale devrait avoir comme signature
    -(void) setScale:(CGFloat) aScale

    Le fait de l'avoir déclaré en IBACtion doit perturber le mécanisme des bindings (voir la doc sur Key Value Observing)
  • IlluminatiIlluminati Membre
    18:36 modifié #3
    Effectivement, j'ai mélangé de manière brouillonne actions et bindings... Le plus curieux, c'est que ça "marchait", le problème de la valeur de retour provenant de l'ordre d'appel des awakeFromNib.

    C'est maintenant corrigé en devenant KVC/KVO et en retirant les actions inutiles ainsi qu'en faisant un set initial dans le awakeFromNib du contrôleur.

    Merci.
  • Philippe49Philippe49 Membre
    18:36 modifié #4
    dans 1206355628:

    Le plus curieux, c'est que ça "marchait"


    Pas tant que ça, les appels de méthode sont transmis par
    id objc_msgSend(id theReceiver, SEL theSelector, ...)
    et si le receiver peut répondre, et c'était le cas dans ta méthode, cela se passe correctement.
    Par contre au niveau du KVO cela reste moins clair.
Connectez-vous ou Inscrivez-vous pour répondre.