[newbie][delegate]

olofolof Membre
13:33 modifié dans API AppKit #1
Bonjour à  tous !

Pour commencer, je débarque complètement dans Cocoa. Je viens de terminer la lecture du livre 'Cocoa par la pratique'.

Ensuite, j'espère que je poste dans le bon forum...

En listant quelques documents sur le site developpeur d'Apple, j'ai eu envie de m'assurer que j'avais bien compris le concept de "delegate". Mon but est donc de créer une application Cocoa, avec une fenêtre (vide) et de faire un delegate qui interdit la fermeture de la dite fenêtre. Vu comme ça, ça m'a paru super simple. Et ben non, j'y suis même pas arrivé  :'(

Voilà  ce que j'ai fait :

- nouveau projet "Cocoa Application"
- ouverture du MainMenu.nib dans IB
- création d'une sous-classe de NSApplication (MyApplication)
- Définition de la custom class de File's Owner à  MyApplication
- Liaison entre l'instance Window et File's Owner et connection de l'outlet Delegate
- Création des fichiers de ma classe MyApplication

MyApplication.h :

<br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface MyApplication : NSApplication<br />{<br />}<br /><br />-(BOOL)windowShouldClose:(id)sender;<br /><br />@end<br />


MyApplication.m :

<br />#import &quot;MyApplication.h&quot;<br /><br />@implementation MyApplication<br /><br />-(BOOL)windowShouldClose:(id)sender{<br />	NSLog(@&quot;windowShouldClose&quot;);<br />	return NO;<br />}<br /><br />@end<br />


Et bien entendu, la fenêter se ferme sans autres...

Si une âme charitable veut bien me consacrer quelques minutes  ???


Merci beaucoup !!!

Réponses

  • octobre 2005 modifié #2
    Tu cherche à  rendre impossible la fermeture de ta fenêtre ? Si oui, ds la palette "Attributes" de IB, tu décoches l'option "Close" de ta window :p

    Pour le delegate :
    Il ya des méthodes delegate pour quelques classes (je vais pas les lister :p) enfin quasiment toutes.
    Par exemple une fenêtre, tu connectes ta window à  ton file's owner par un delegate.
    Ensuite, en fouillant la doc apple, on trouve des methodes delegate pour NSWindow. Par exemple :
    - (void)windowDidClose:(NSNotification *)n
    

    implémente cette méthode ds ton fichier implémentation (.m) comme ceci
    <br />- (void)windowDidClose:(NSNotification *)n<br />{<br /> NSLog(@&quot;Ma fenêtre est fermée et je suis heureux&quot;);<br />}<br />
    

    Tu n'as mm pas besoin de mettre - (void)windowDidClose:(NSNotification *)n; dans ton header (.h)


    Heu sinon, j'ai jms tenté de remplacer le file's owner de MainMenu.nib et je pense qu'il vaut mieux pas, ça équivaut à  NSApplication je crois.
    Crée carément une nouvelle classe et "instantiate" la dans ton NIB et relie la window à  cette nouvelle classe par un delegate.

    Voilà  je viens de trouver !
    Tu crées une sous-classe de NSObject
    Ton header :
    <br />/* MyObject */<br /><br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface MyObject : NSObject<br />{<br />    IBOutlet NSWindow *window;<br />}<br />- (BOOL)windowShouldClose:(NSWindow *)window;<br />- (IBAction)close:(id)sender;<br /><br />@end<br />
    

    Ton fichier implem. :
    <br />#import &quot;MyObject.h&quot;<br /><br />@implementation MyObject<br /><br />- (IBAction)close:(id)sender<br />{<br />	[window performClose:nil];<br />}<br /><br />- (BOOL)windowShouldClose:(NSWindow *)window<br />{<br />	NSLog(@&quot;Window should close ?&quot;);<br />	return NO;<br />}<br /><br />@end<br />
    


    N'oubli pas les connexions ds Interface Builder
    Tu auras donc une fenêtre et ds cette fenetre : un bouton qui effectuera l'action close.

    Pourquoi le "performClose:" ? Tout simplement parce qu'il est marqué ds la documentation que - (BOOL)windowShouldClose:(id)sender sera appelé que si la fenêtre est fermée, soit en quittant l'application, soit en effectuant un "performClose:"

    @+
  • olofolof Membre
    13:33 modifié #3
    Salut Eaglelouk,

    en effet, j'avais pas vu dans la doc qu'il fallait un performClose: !


    Merci beaucoup !

    Et sûrement à  bientôt avec d'autres questions de newbie  :o
  • Eddy58Eddy58 Membre
    octobre 2005 modifié #4
    dans 1129065483:

    en effet, j'avais pas vu dans la doc qu'il fallait un performClose: !

    La méthode performClose: n'est pas une obligation, tu peux trés bien t'en passer en implémentant seulement le delegate windowShouldClose.
    En faites, le delegate windowShouldClose sera appelé :
    - Soit quand le bouton de fermeture classique sera cliqué.
    - Soit quand dans ton code tu donneras l'ordre toi-même de fermer la fenêtre via la méthode performClose. Eaglelouk a choisi l'exemple d'une action pour illustrer ceci.

    Si tu as d'autres questions, n'hésites pas, et bienvenue sur OC olof. :)
  • 13:33 modifié #5
    Je suis étonné que ce tu as expliqué ne marche pas. À tout hasard, tu ne te serais pas trompé dans le sens de la connexion. Il s'agit de commencer la liaison sur la fenêtre et terminer sur le File's owner. Je dis ça car on se trompe souvent au début dans le sens des connexions, et que dans ce cas précis, le file's owner étant de classe NSApplication a aussi un outlet delegate.

    Sinon petit détail: tu n'es pas obligé de déclarer les méthodes de delegate dans le .h. Ces méthodes sont déclarées sous forme de catégories de NSObject, donc toutes les classes les déclarent aussi.

    dans 1129068720:

    Si tu as d'autres questions, n'hésites pas, et bienvenue sur OC olof. :)

    Serais-tu sensible à  son avatar par hasard?
  • Eddy58Eddy58 Membre
    13:33 modifié #6
    dans 1129070606:

    Serais-tu sensible à  son avatar par hasard?

    Je t'avouerais que je suis pas un fan assidu de la Kro, mais il est aussi vrai que je ne suis pas contre de temps en temps... :P :p
  • 13:33 modifié #7
    J'ai fais la même chose que Olof au départ, en me disant que le bouton de fermeture de la fenêtre suffira a appelé windowShouldClose.
    Aucun effet  :o
  • olofolof Membre
    13:33 modifié #8
    dans 1129093872:

    J'ai fais la même chose que Olof au départ, en me disant que le bouton de fermeture de la fenêtre suffira a appelé windowShouldClose.
    Aucun effet  :o

    Comme expliqué dans mon 2ème post, j'ai fait ce que Eaglelouk m'a proposé, à  savoir mettre un bouton dans la fenêtre qui fait un performClose:. Et ça fonctionne. Mais hier soir, je m'étais arrêté là .
    Ce matin, j'ai viré ce bouton et sa méthode qui faisait le performClose: et ça marche !!!  :p

    En résumé, j'ai une classe MonDelegate, que j'ai instanciée dans IB. Lien de la fenêtre à  ma classe et connexion du delegate. Et c'est tout.

    Merci à  tous !
  • 13:33 modifié #9
    Un petit détail m'avait échappé hier: le File's owner doit être chargé avant le nib, il doit donc exister avant le chargement du nib, ce n'est donc pas le nib qui peut définir sa classe. C'est donc que la "classe de l'application" est définie ailleurs, et ce ailleurs est justement dans l'info.plist à  la clé NSPrincipalClass. Si tu changes la valeur associée à  cette clé, ça marche.
Connectez-vous ou Inscrivez-vous pour répondre.