Raffraichir l'affichage au démarrage

meallmeall Membre
17:56 modifié dans API AppKit #1
Bonjour,

J'ai une petite application simple qui lit certaines données d'un array et le totu fait entièrement avec du binding. Vraiment cool, car le binding m'a fait sauver beaucoup de temps, mê^me si j'en ai perdu à  comprendre la mécanique!

J'ai cependant un petit problème: lorsque j'ouvre l'application, pas tout les champs sont raffraichies. Ceux qui sont bindé sur mon array, aucun problème. Mais les autres sont calculés à  partir des données de l'array, docn je voudrais refaire le calcul lorsque la fenêtre s'affiche la première fois. J'ai tenté d'appeler ma procédure de calcul dans le awakeFromNib, niet. J'ai regarder aussi du coté des notifications du NSWindow, mais c'est pas concluant. Le NSWindowDidUpdateNotification "update" la fenêtre seulement si je bouge la souris, et le fait d'ailleurs chaque fois que je bouge la souris inutilement. J'en ai essayé d'autres, mais pas plus agréable.

Bref, je cherche donc à  faire les calculs de ma fenêtre à  l'ouverture initiale, un truc simple que vous pouvez suggérer?

Merci

Réponses

  • AliGatorAliGator Membre, Modérateur
    17:56 modifié #2
    dans 1126957306:

    Bonjour,

    J'ai une petite application simple qui lit certaines données d'un array et le totu fait entièrement avec du binding. Vraiment cool, car le binding m'a fait sauver beaucoup de temps, mê^me si j'en ai perdu à  comprendre la mécanique!

    J'ai cependant un petit problème: lorsque j'ouvre l'application, pas tout les champs sont raffraichies. Ceux qui sont bindé sur mon array, aucun problème. Mais les autres sont calculés à  partir des données de l'array, docn je voudrais refaire le calcul lorsque la fenêtre s'affiche la première fois. J'ai tenté d'appeler ma procédure de calcul dans le awakeFromNib, niet. J'ai regarder aussi du coté des notifications du NSWindow, mais c'est pas concluant. Le NSWindowDidUpdateNotification "update" la fenêtre seulement si je bouge la souris, et le fait d'ailleurs chaque fois que je bouge la souris inutilement. J'en ai essayé d'autres, mais pas plus agréable.

    Bref, je cherche donc à  faire les calculs de ma fenêtre à  l'ouverture initiale, un truc simple que vous pouvez suggérer?

    Merci
    Tu dis que tu as essayé de refaire ton calcul dans le awakeFromNib:, ce qui me semble la bonne solution, mais quand tu as fait cela tu as peut-être oublié, une fois le calcul refait, de rafraà®chir ton affichage ?
    Par exemple si tu as des TableViews, un petit [matableView reloadData] permet de forcer à  recharger les données et mettre à  jour la table pour faire correspondre l'affichage aux données.
    Si c'est des popupmenus je crois que c'est pareil, ou dans le même gout, que reloadData.

    Un setNeedsDisplay: sur des NSViews aussi si tu dessines des données.

    etc...
  • meallmeall Membre
    septembre 2005 modifié #3
    dans 1126958545:

    Tu dis que tu as essayé de refaire ton calcul dans le awakeFromNib:, ce qui me semble la bonne solution, mais quand tu as fait cela tu as peut-être oublié, une fois le calcul refait, de rafraà®chir ton affichage ?
    Par exemple si tu as des TableViews, un petit [matableView reloadData] permet de forcer à  recharger les données et mettre à  jour la table pour faire correspondre l'affichage aux données.
    Si c'est des popupmenus je crois que c'est pareil, ou dans le même gout, que reloadData.

    Un setNeedsDisplay: sur des NSViews aussi si tu dessines des données.

    etc...


    Merci pour le truc, mais le résultat est le même. J'ai fait un setNeedsDisplay sur un NSTextField, mais niet, same results!

    J'ai fait un test. J'ai mit un NSLog qui affiche un des NSTextField bindés (ce sont tous des NSTextField en passant) et lors de la sortie du awakeFromNib la valeur est encore à  zéro. Je me suis donc mit a pensé: est-ce possible que l'affichage des binding se fait plus tard que le awakeFromNib? y a-t-il un équivalent de awakeFromBind ou une notification sur les bind?
  • Eddy58Eddy58 Membre
    17:56 modifié #4
    J'ai eu affaire à  ce genre de problème dans mon projet en cours (sans bindings). Mes outlets vers les autres classes où je récupérais les données pour mes calculs me donnaient de fausses valeurs, et ça m'affichait n'importe quoi. En temporisant la fin de l'initialisation, afin d'attendre la connection de tout les outlets, là  pas de problème, mais bon ça faisait un décalage d'affichage à Â  l'ouverture de l'appli. Je dis "faisait", car quand ma méthode awakeFromNib s'est allongée au niveau code, je n'ai plus eu besoin de cette tempo.
    Ceci dit, la méthode awakeFromNib est censée s'exécuter quand tout les outlets ont été connectés, donc je comprend pas ce problème, et comment y remédier proprement dès le début du développement. ???
    [tt]
    -(void)awakeFromNib
    {
    /*
    ...
    */

    [self performSelector:@selector(finInit) withObject:nil afterDelay:0.1];
    }

    -(void)finInit
    {
       // Remplissage des controls
    }
    [/tt]
  • meallmeall Membre
    17:56 modifié #5
    dans 1127057762:

    J'ai eu affaire à  ce genre de problème dans mon projet en cours (sans bindings). Mes outlets vers les autres classes où je récupérais les données pour mes calculs me donnaient de fausses valeurs, et ça m'affichait n'importe quoi. En temporisant la fin de l'initialisation, afin d'attendre la connection de tout les outlets, là  pas de problème, mais bon ça faisait un décalage d'affichage à Â  l'ouverture de l'appli. Je dis "faisait", car quand ma méthode awakeFromNib s'est allongée au niveau code, je n'ai plus eu besoin de cette tempo.
    Ceci dit, la méthode awakeFromNib est censée s'exécuter quand tout les outlets ont été connectés, donc je comprend pas ce problème, et comment y remédier proprement dès le début du développement. ???
    [tt]
    -(void)awakeFromNib
    {
    /*
    ...
    */

    [self performSelector:@selector(finInit) withObject:nil afterDelay:0.1];
    }

    -(void)finInit
    {
       // Remplissage des controls
    }
    [/tt]



    drole de workarround... Si tel problème existe, je peux pas croire que nous somes les 2 seuls à  l'avoir vécu et qu'Apple ne fera rien pour ça... :brule:

    Cependant, je dois avouer, ça fonctionne! Merci pour le truc, je vais le retenir pour le futur...
  • 17:56 modifié #6
    Personnellement, j'attends : - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    Au moins je suis sûr que tout est "bien" chargé : )
  • meallmeall Membre
    17:56 modifié #7
    dans 1127067853:

    Personnellement, j'attends : - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    Au moins je suis sûr que tout est "bien" chargé : )


    Bonne idée, mais dans mon cas (je viens de l'essayer) il semble que les valeurs bindé sont encore nulle selon l'output du NSLog. Donc le résultat est le même...

    Cepe3ndant, mes NSLog me montre que NSApplicationDidFinishLaunchingNotification est lancé après le awake from NIB. C'est déjà  un départ, mais c'est encore trop vite...
  • MickMick Membre
    17:56 modifié #8
    Bonjour, je déterre ce sujet car il m'est arrivé la même chose...

    J'ai utilisé la technique du performSelector:withObject:AfterDelay:, et cela fonctionne. Cependant, je me demandais si quelqu'un aurait une suggestion pour expliquer le problème?
    Je rappelle le problème qui est quand même simple : des vues à  remplir au démarrage de l'appli :
    <br />- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {<br />	NSTableColumn *uneColonne=[[NSTableColumn alloc] initWithIdentifier:@&quot;nom&quot;];<br />	[[uneColonne headerCell] setTitle:@&quot;Nom&quot;];<br />	[uneColonne setWidth:100.0];<br />	[laTableEtatDesNotes addTableColumn:uneColonne];<br />	[uneColonne release];<br />	uneColonne=[[NSTableColumn alloc] initWithIdentifier:@&quot;prenom&quot;];<br />	[[uneColonne headerCell] setTitle:@&quot;Prenom&quot;];<br />	[uneColonne setWidth:100.0];<br />	[laTableEtatDesNotes addTableColumn:uneColonne];<br />	[uneColonne release];<br />	[self performSelector:@selector(majDemarrage) withObject:nil afterDelay:0.1];<br />}<br />
    


    Un reloadData n'est pas efficace dans la méthode, mais si j'ajoute un performSelectorWithObjectAfterDelay (0.1 seconde) et que j'implémente la méthode appelée avec un simple reloadData cela fonctionne !! Cela paraà®t inimaginable qu'un cas aussi fréquent que de remplir des tables ou autres views au démarrage oblige à  faire des bidouilles de timing !! Peut-être qu'une autre méthode doit être appelée et pas didFinishLaunching.
Connectez-vous ou Inscrivez-vous pour répondre.