2009-09-22 6 views
7

J'essaie d'afficher un NSPanel sous forme de feuille. Je fais naïvement quelque chose le long de ces lignes:Comment afficher un NSPanel sous forme de feuille

SheetController *sheetController = [[[SheetController alloc] 
             initWithWindowNibName:@"Sheet"] autorelease]; 

[[NSApplication sharedApplication] beginSheet:sheetController.window 
           modalForWindow:self.window 
           modalDelegate:self 
           didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) 
            contextInfo:nil]; 

Pour une raison qui m'échappe, cela ne fonctionne pas. Lorsque cette partie du code est appelée, la feuille clignote momentanément (à cause du message). La feuille n'est jamais accrochée à la fenêtre.

Si quelqu'un peut me diriger vers où je peux trouver plus d'information, ce serait très apprécié.

Répondre

16

Cela ressemble à un cas classique d'avoir coché la case "Visible au lancement" pour le panneau dans IB. Éteignez-le.

+0

Spot sur! Merci beaucoup. –

2

Oui, vous devez posséder ce contrôleur aussi longtemps que vous voulez qu'il continue à fonctionner. Vous ne pouvez pas simplement le créer, l'autorelease, et le laisser mourir - vous devez le garder aussi longtemps que vous en avez besoin.

+0

Alors que la suppression du message autorelease empêche la disparition du panneau, il n'est toujours pas accroché à la fenêtre ... Je suis vraiment perplexe. –

+2

Il ne suffit pas simplement de ne pas le libérer. C'est juste une fuite. Vous devez posséder ce que vous avez créé et le relâcher quand vous en avez fini (et * seulement * alors). Pour ce qui est de raccorder le contrôleur à la fenêtre qu'il contrôle, vous devez vous assurer que vous avez défini la classe du propriétaire du fichier, puis connectez la sortie 'window' de votre contrôleur à la fenêtre. Vous faites les deux dans IB. –

1

N'oubliez pas que si vous essayez de l'exécuter en tant que feuille "modale" (c'est-à-dire qu'elle prend en charge l'application jusqu'à ce que l'utilisateur la rejette), vous devrez pousser une nouvelle boucle d'exécution. Ce que vous avez fait est montré la feuille, et puis pas poussé une nouvelle boucle, de sorte que le système d'exploitation montre juste la feuille, voit qu'il n'y a aucune raison de la maintenir, et l'arrête ainsi et reprend l'exécution sur le prochain ligne:

Je fais généralement des feuilles de la manière suivante:

- (id)showPanelModalAgainstWindow: (NSWindow *)window 
{ 
    [[NSApplication sharedApplication] beginSheet: panelToShow 
       modalForWindow: window 
       modalDelegate: self 
       didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) 
       contextInfo: nil]; 

    [[NSApplication sharedApplication] runModalForWindow: panelToShow]; 
    if (m_returnCode == NSCancelButton) return nil; 
} 


- (void)sheetDidEnd:(NSWindow *)sheet 
     returnCode:(int)returnCode 
     contextInfo:(void *)contextInfo 
{ 
    UNUSED(sheet); 
    UNUSED(contextInfo); 
    m_returnCode = returnCode; 
} 

Ensuite, dans votre accepter et/ou annuler les routines bouton:

- (IBAction)continueButtonClicked:(id)sender 
{ 
    UNUSED(sender); 
    [[NSApplication sharedApplication] stopModal]; 
    [createAccountWizardPanel orderOut: nil]; 
    [[NSApplication sharedApplication] endSheet: createAccountWizardPanel 
             returnCode: NSOKButton]; 

} 

Je suis sûr qu'il est aussi légèrement moins de code-y, mais je ne l'ai pas examiné en profondeur, car cette façon fonctionne parfaitement bien jusqu'ici ....

Les commentaires précédents sur la durée de vie du contrôleur et des objets du panneau sont également pertinent - assurez-vous de comprendre exactement quels objets vous avez besoin pour quelle durée de vie lors de l'affichage d'un panneau modal.

+0

Cette méthode est obsolète :( – ColdSteel

Questions connexes