Hiérarchie de vue
UniX
Membre
Salut.
Voilà , j'ai une vue perso que j'affiche dans une NSScrollView. Maintenant, je voudrais pouvoir afficher une image en haut de ma vue, c'est à dire avoir une image positionnée par exemple à 50 du bord gauche et 50 du haut, mais lorsque je bouge avec mes scrollers, elle ne doit pas bouger de place .... Je sais pas si je suis clair, c'est comme une incrustation sur une vidéo ....
Cette image je la construis dans une NSView perso. Je me dis donc, il suffit de la rendre subview de la NSScrollView, et le tour est joué. Mais non, car elle s'éfface dès que je bouge mes scrollers ....
Quelle est la bonne démarche à suivre ...?
Voilà , j'ai une vue perso que j'affiche dans une NSScrollView. Maintenant, je voudrais pouvoir afficher une image en haut de ma vue, c'est à dire avoir une image positionnée par exemple à 50 du bord gauche et 50 du haut, mais lorsque je bouge avec mes scrollers, elle ne doit pas bouger de place .... Je sais pas si je suis clair, c'est comme une incrustation sur une vidéo ....
Cette image je la construis dans une NSView perso. Je me dis donc, il suffit de la rendre subview de la NSScrollView, et le tour est joué. Mais non, car elle s'éfface dès que je bouge mes scrollers ....
Quelle est la bonne démarche à suivre ...?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
-2 NSScroller
-1 NSClipView (dont la subview est le document)
- éventuellement des NSRulerView.
Pour disposer les subviews dans la scrollview, il faut surcharger la méthode -tile.
Donc dans ton cas, tu rajoutes ta vue dans les subview de la scrollview et définit son frame dans la méthode -tile (n'oublie pas le [super tile]; ).
(Genre on la met en dehors et ensuite un utilises les flèches pour déplacer la vue ?)
Bon, il va donc falloir que je regarde cette méthode -tile .....
Parceque la doc de la méthode tile: n'est pas vraiment très explicite .....
[tt]-(void)tile {
[super tile];
NSRect r;
//le calcul pour définir le frame de ton imgae
[uneImageView setFrame:r];
}[/tt]
La sous-classe de NSSCrollView :
et vueAfficheurs est une variable d'instance de mon controlleur initialisée comme ceci :
Et dans IB, j'ai bien entendu mis ma classe JCScrollView comme classe perso de la scroll view.
Mais pas mieux .... j'ai toujours rien qui s'affiche.
N'initialise pas de vue dans le tile. ça sert juste à diposer les subviews de la scrollview, ce qui implique qu'elles existent préalablement.
Et accessoirement ta vue doit être une variable d'instance de la scrollview. Aller chercher des valeurs 'à l'extérieur' comme tu le fais, ça ne se fait pas.
Donc:
1. Tu définis une vue afficheur comme variable d'instance;
2. Tu rajoutes des méthodes pour permettre à ton contrôleur de modifier les valeurs de la vue et y accéder;
3. Tu surcharges initWithFrame et tu y initialises là (et pas ailleurs) cette sous-vue, tu la rajoutes dans les subviews;
4. Tu la releases ds le dealloc, que tu surcharges également;
5. Tu surcharges le tile.
Voici ma classe :
Alors, plusieurs soucis.
1) l'appli ne passe pas par la méthode initWithFrame: de cette classe. J'ai donc mis le code contenu dans la méthode ailleurs pour faire les essais.
2) maintenant, j'ai ma vue qui s'affiche au dessus de la scroll view, mais dès que je bouge un scroller ou que je zoome, elle disparaà®t.
Bon, petiti à petit on avance ....
à‰ventuellement, utilise:
[self addSubview:vueAfficheurs positioned:NSWindowAbove relativeTo:[self documentView]];
Il faut demander à redessiner la vue ? Parceque quand je mets la fenetre dans le dock et que je ressors, hop elle est de nouveau là ....
Vous avez oublié la règle d'or : on ne peut (doit) pas empiler des NSViews de même niveau.
Donc 2 views qui sont soeurs ne doivent absolument pas se chevaucher.
En effet, il y en aura toujours une qui recouvra l'autre quand son drawRect: sera appellé.
De plus, l'ordre d'appel des drawRect: est complètement aléatoire, en fonction des demandes de mise à jour par le système. Dans ton cas, à l'initialisation, il semble bien que le dernier drawRect: appelé est celui de ton "Afficheur". Mais quand tu scrolles, c'est la NSClipView qui est mise à jour, et donc, c'est son drawRect: qui est utilisé, recouvrant ainsi ton "Afficheur".
Dans le code de Unix, les 2 soeurs sont sa vue "Afficheur" et la NSClipview.
La méthode tile sert justement à modifier les frames de chaque soeurs afin qu'elles ne se chevauchent pas. Ce qui n'est pas fait dans l'implémentation de cette méthode par Unix.
Moi, j'aimerai savoir ce que veut faire (visuellement parlant) Unix. Car il y a peut-être d'autres solutions plus simples.
Eventuellement, fais nous un petit montage genre screenshot pour qu'on voit vraiment ce que tu veux.
.
Effectivement comme l'a dit Bru, les 2 vues se chevauchent.
Sur l'image 2, on voit le scroller horizontal qui est décalé vers la droite, pour afficher la partie droite de l'image. Mais la vueAfficheurs, elle, n'a pas bougé.
C'est ce que je veux obtenir.
Une child window est une fenêtre qui est attachée à une fenêtre mère (en l'occurence, celle qui contient le srcollView).
.
1. dans IB, création d'une custom view pour y mettre les éléments que tu veux, avec l'outlet qui va bien.
2. dans Xcode, création d'une fenêtre sans bordure :
[tt]NSWindow *wnd=[[NSWindow alloc] initWithContentRect:[customView bounds] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];[/tt]
3. utilisation de la custom view comme content-view de cette fenêtre :
[tt][wnd setContentView:customView];[/tt]
4. ajout de cette fenêtre comme child-window:
[tt][[tableView window] addChildWindow:wnd ordered:NSWindowAbove];[/tt]
5. affichage de la fenêtre
[tt][wnd orderFrontRegardless];[/tt]
Le plus dur est de déterminer les coords de la child window pour qu'elle soit au dessus de la scrollView.
.
Coool ! J'ai réussi à obtenir ce que je voulais : un grand merci Renaud et Bru !
2 petites dernières précisions :
- ma scrollview se trouve en fait sur un onglet de NSTabView, et bien entendu, je ne souhaite voir la child window que lorsque le bon onglet est affiché, quelle est la méthode la plus appropriée pour masquer/afficher cette child windows ?
- si au lieu d'avoir une image dans ma vue vueAfficheurs, j'ai un NSBezierPath, est-il possible de rendre le fond de la vue (et de la child window ?) transparent (pour voir à travers la vue partout ou je n'ai pas dessiné avec le bezier) ?
- Pour cacher ta fenêtre tu fais un simple orderOut: dessus et un orderFrontRegardless pour la montrer.
Pour contourner le problème, lorsque l'onglet change pour afficher la vue parent, je positionne la fenêtre child, je la rend child de sa parent, et je la montre. A l'inverse, lorsque l'onglet rechange, je la "déchild" puis je la cache.
C'est cool. Merci à tous. Vive Objective-Cocoa
C'est étrange ce que tu dis là ...
orderOut fonctionne chez moi pour les child windows...
.
La fenêtre principale disparaà®t un bref instant et réapparaà®t, mais la child est toujours là .....
Pourtant, lors de son initialisation, j'ai bien fait un [maFenetre setOpaque:NO] ...
et là ça fonctionne.