NSImageView s'affiche, pas une sous-classe de NSImageView

bofxyz

Membre confirmé
26 Juillet 2012
85
1
Bonjour
OSX10.7.5 - Xcode 4.6.2

Marche parfaitement : imageView visible ; le glisser-coller pas, ce qui est attendu.
Bloc de code:
 - (IBAction)drag:(id)sender {
   NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 10, 100, 50)];
    NSView * winView = [_window contentView];
    [winView addSubview:imgView];
    [imgView setImageFrameStyle:NSImageFramePhoto]; 
    [imgView setEditable:YES];
}

Marche pas : imageView invisible ; le glisser-coller OK, ce qui est attendu.
Bloc de code:
@interface ImageView : NSImageView < NSDraggingDestination>
...
- (IBAction)drag:(id)sender {
    ImageView *imgView = [[ImageView initWithFrame:CGRectMake(10, 10, 100, 50)];
    NSView * winView = [_window contentView];
    [winView addSubview:imgView];
    [imgView setImageFrameStyle:NSImageFramePhoto]; 
    [imgView setEditable:YES];
}

J'utilise ImageView pour récupérer les événements, ici glisser une image dans imgView.
Le comble, c'est que le glisser marche parfaitement : draggingEnded est bien exécuté !
Normal, puisque imageView est bien présent dans les subviews de la view de window.
Mais sans l'affichage de imageView, pas de cadre...

Je rate sûrement quelque chose, mais quoi ?

Merci de l'aide.
 
Documentation:
A hidden view disappears from its window and does not receive input events. It remains in its superview’s list of subviews, however, and participates in autoresizing as usual. The Application Kit also disables any cursor rectangle, tool-tip rectangle, or tracking rectangle associated with a hidden view. Hiding a view with subviews has the effect of hiding those subviews and any view descendants they might have. This effect is implicit and does not alter the hidden state of the receiver’s descendants as reported by isHidden.
 
Merci.
Je récupère mouseDown et draggingEnded, donc imageView n'est pas hidden. D'ailleurs si je fait
[imageView setHidden:NO], rien ne change.
J'ai créé avec IB un textField, sous-classe de NSTextField, dans les mêmes conditions. Même causes, mêmes effets.
Si je comprends bien c'est fromage ou dessert.
Dans IB.
Avec les classes NS..., comportement normal, mais aucune possibilité de gestion des mouseDown, draggingEnded et autres évènements.
Avec des sous-classes des classes NS..., aucun comportement normal, mais gestion des évènements.
Je vais essayer de me passer de IB...
 
Ca avance...
Toujours rien par IB.
Par programmation.
En superposant une sous-classe de NSImageview ImageView et une sous-classe de NSView View (même frame), je récupère mouseDown, rightMouseDown. Sur le second j'affiche un menu contextuel, qui marche.
Il faut sans doute les deux : ImageView pour les images, View pour les évènements.
Le glisser d'une image dans ImageView marche bien. Par contre je ne réussi pas à intercepter l'évènement de fin de glisser.
Rien n'est parfait.
Si quelqu'un a des idées ?
 
J'ai réussi des choses, mais en passant par des portes de derrière et ce n'est pas robuste. En fait, il me manque la porte principale.
Par programmation (cad sans IB), je n'arrive pas à afficher une instance "imageView" de la sous-classe "ImageView" de la classe "NSImageView". C'est sûrement possible !
Un exemple SVP.
Merci de l'aide.
 
Je ne sais pas si je suis le seul mais je trouve tes explications pas claires du tout.

Pour qu'une vue gère le drag&drop tu as juste à sous-classer et implémenter quelques méthodes dans la sous-classe (pas toutes nécessaires, cf doc) :

Bloc de code:
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
-(void)draggingEnded:(id <NSDraggingInfo>)sender
-(void)draggingExited:(id <NSDraggingInfo>)sender
-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender

Et bien sur s'enregistrer en tant que destination (dans init… par example)

Bloc de code:
[self registerForDraggedTypes:@[CF_DOCUMENTATION]];

Par code ou IB ça change rien, mais peut-être que faire en codant c'est mieux pour comprendre les choses dans un premier temps.
 
Ouf !
Effectivement, par programmation ça permet de mieux comprendre, au moins pour moi.
La solution à mon problème est simple, maintenant que je l'ai trouvée.
Il suffit de commenter (plutôt que de supprimer) la méthode drawRect générée automatiquement par xcode
lors de la création de la sous-classe ImageView. Pourquoi ? Je devine un peu... Ce n'est peut être pas très réglementaire, mais ça marche.
Je garde la méthode initWithFrame de ImageView : normal elle fait appel à celle de la classe NSImageView, qui n'est pas vide, mais dont je ne sais pas voir le contenu.
Maintenant, je sais afficher une image, faire du glisser-coller d'image, intercepter les évènements de la souris, etc.

Grand merci à tous.

PS : j'enverrai le code à toute personne, qui me contactera par messagerie privée.