How to show a NSPanel as a sheet

十年热恋 提交于 2019-12-05 22:52:41

问题


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.


回答1:


This sounds like a classic case of having checked the "Visible at Launch" box for the panel in IB. Turn that off.




回答2:


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.




回答3:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!