Savoir quand une vue apparaà®t
Céroce
Membre, Modérateur
Bonjour à tous.
Voilà mon soucis: j'ai besoin d'initialiser des rectangles à chaque fois que ma vue apparaà®t, et non pas à chaque fois que ma vue est créée.
Le problème, c'est que cette vue est comprise dans un NSPanel (utilisé en Sheet) qui est conservé en mémoire après son premier chargement. Quand le panneau est masqué, la vue n'est donc pas détruite, et donc sa méthode -initWithFrame: n'est pas rappelée lors du prochain affichage du panneau.
Je n'ai pas trouvé de notification ou de méthode appelées lorsque la vue s'affiche. Quelqu'un aurait-il une suggestion ?
Merci d'avance,
Céroce
Voilà mon soucis: j'ai besoin d'initialiser des rectangles à chaque fois que ma vue apparaà®t, et non pas à chaque fois que ma vue est créée.
Le problème, c'est que cette vue est comprise dans un NSPanel (utilisé en Sheet) qui est conservé en mémoire après son premier chargement. Quand le panneau est masqué, la vue n'est donc pas détruite, et donc sa méthode -initWithFrame: n'est pas rappelée lors du prochain affichage du panneau.
Je n'ai pas trouvé de notification ou de méthode appelées lorsque la vue s'affiche. Quelqu'un aurait-il une suggestion ?
Merci d'avance,
Céroce
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Elle est appelee a chaque fois que l'on a besoin de redessiner toute ou une partie de la vue.
- windowWillBeginSheet:
- windowDidEndSheet:
Ici le moderateur. Les blagues concernant le cannabis ne doivent pas enfumer les discutions sur la programmation.
Bon, blagues a part, les methodes donnees par mpergand et ClicCool sont meilleures tant que ta vue est dans une (pas de ClicCool a l'horizon) shit.
Je ne m'y suis pas encore remis, mais j'ai étudié vos 3 propositions:
La méthode drawRect: de fouf
Non, c'est pas possible. Comme je l'écrivais, je veux initialiser les coordonnées de rectangles (d'un rectangle de sélection dans ma vue, en particulier) quand la vue s'affiche. Hors, drawRect: est appelée à chaque fois que la vue doit être redessinée, par exemple si tu changes la taille de la fenêtre, ou que tu la fais passer au 1er plan.
La méthode windowDidBecomeKey de ClicCool
Pas possible non plus. Si tu fais passer la fenêtre en arrière plan (par exemple en sélection une autre fenêtre de l'appli) et que tu la ramène au 1er plan, les rectangles vont être initialisés, alors qu'ils devraient rester tels quels.
La méthode - windowWillBeginSheet: de mpergand
Celle qu'il faut que j'étudie de + près.
En fait, au départ, je me demandais surtout s'il n'existait pas une méthode du style viewDidDisplay: que j'aurais loupée...
Encore merci de vos réponses rapides et de qualité.
Une vue n'a faire que ce qu'elle sait faire : monter/afficher des choses... Je ne vois donc pas pourquoi on y mettrait du code d'initialisation qui n'est pas lié à la vue elle même (si ce n'est que pour en afficher le résultat).
C'est bien toi, à travers ton programme, qui commande l'apparition du panel (sheet). Donc c'est bien à ce moment que tu dois déclancher cette initialisation.
Le code d'initialisation peut être contenu dans une méthode spécifique ajoutée à ta sous classe (pardon à ta classe dérivée) que tu appelles avant le beginSheet...
Les drawRect: suivant auront alors leurs rectangles correctement initialisés.
.
Oui, c'est bien la méthode qu'il faut utiliser, mais ça n'a rien d'évident.
La vraie difficulté de la programmation objet reste toujours de répartir les responsabilités de chaque objet.
Une vue ne fait pas qu'afficher des choses. Elle gère aussi des évenements: clics, entrées dans la vue du curseur, saisies au clavier, glisser-déposers...
Mon objet permet de faire la sélection d'une zone d'une image pour la recadrer. D'ailleurs, au départ, ça m'avait semblé plus logique que ce soit un NSControl.
Pourquoi le fait que la vue positionne elle-même un rectangle de sélection par défaut ne serait pas de son ressort ?
Cocoa requiert une certaine tournure d'esprit que je n'ai pas encore bien intégrée, mais il n'y a rien d'évident.
C'est clair, j'ai simplifié le concept de view à des fins d'exemple... Mias il faut bien voir la view comme une NSResponder, donc susceptible d'interagir avec l'utilisateur.
Ce n'est que dans ce message n°7 que tu nous expliques un peu mieux ce que tu veux faire... Excuse-nous alors d'avoir été imprécise auparavant !
J'en profite pour rebondir, sachant un peu mieux ce que tu veux réaliser.
Pour ton projet, je passerai plutôt par la création d'un objet spécifique dont la NSView est une composante (celle qui permet l'affichage à des fins de visualisation, mais aussi d'interaction avec l'utilisateur). C'est du moins comme cela que procède Apple pour beaucoup de ses classes (Comme les NSControl, qui délèguent leur affichage une NSCell).
Cet objet s'occuperait de tout ce qui est traitement d'image (recadrage, mais aussi tout ce que tu veux) et ferait appel à sa view attachée pour afficher et attendre les actions de l'utilisateurs.
.
Pour ce qui est de ta suggestion, c'est bien ainsi que c'est fait. C'est mon objet au niveau modèle qui va effectivement réaliser le recadrage. La vue ne fait que renvoyer les coordonnées du rectangle de sélection. En relisant ce que j'avais écrit, on peut effectivement croire que je voudrais que la vue elle-même fasse le recadrage.
[tt]
-(BOOL)becomeFirstResponder
{
    [self setNeedsDisplay:YES];
    return [super becomeFirstResponder];
}
[/tt]
Non, c'est pas la bonne solution:
1 - Rien ne dit qu'il n'y aura pas d'autre Responder dans la Sheet, par exemple un Text Field.
2 - Ramener la fenêtre contenant la Sheet au 1er plan appelerait cette méthode, alors que le but est d'initialiser la vue uniquement lorsqu'elle apparaà®t.
Merci toutefois de ta suggestion.
Il me semble que c'est ce que Bru avait suggéré plus haut ::)