I'm trying to show a NSPanel as a sheet. I'm naively doing something along those lines:
SheetController *sheetController = [[[SheetController alloc]
initWithWindowNibName:@"Sheet"] autorelease];
[[NSApplication sharedApplication] beginSheet:sheetController.window
modalForWindow:self.window
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
For some reason that eludes me, this isn't working. When this part of the code is called, the sheet momentarily flashes (because of the autorelease
message). The sheet is never hooked to window.
If anyone can point me to where I can find more information, that would be very appreciated.
This sounds like a classic case of having checked the "Visible at Launch" box for the panel in IB. Turn that off.
Yes, you need to own this controller for as long as you want it to continue functioning. You can't just create it, autorelease it, and let it die—you need to hold onto it for as long as you need it.
Don't forget that if you're trying to run this as a "modal" sheet (i.e. it takes over the app until the user dismisses it), you'll need to push a new run loop.
What you've done is shown the sheet, and then not pushed a new loop, so the OS just shows the sheet, sees there's no reason to keep it running, and thus shuts it down and resumes execution on the next line:
I typically do sheets the following way:
- (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;
}
Then, in your accept and/or cancel button routines:
- (IBAction)continueButtonClicked:(id)sender
{
UNUSED(sender);
[[NSApplication sharedApplication] stopModal];
[createAccountWizardPanel orderOut: nil];
[[NSApplication sharedApplication] endSheet: createAccountWizardPanel
returnCode: NSOKButton];
}
I'm sure there is a slightly less code-y way of doing this, but I've not looked to deeply into it, because this way works perfectly fine thus far ....
Previous comments about the lifetime of the controller and panel objects are also relevant -- be sure to understand exactly what objects you need for what lifetimes when showing a modal panel.
来源:https://stackoverflow.com/questions/1457688/how-to-show-a-nspanel-as-a-sheet