如何将NSPanel显示为工作表

时间:2009-09-22 01:17:02

标签: objective-c cocoa nswindow cocoa-sheet

我正在尝试将NSPanel显示为工作表。我天真地做着这样的事情:

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

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

由于某些原因导致我失败,这是行不通的。当调用此部分代码时,工作表会暂时闪烁(因为autorelease消息)。纸张永远不会挂在窗户上。

如果有人能指出我可以找到更多信息的地方,那将非常感激。

3 个答案:

答案 0 :(得分:16)

这听起来像是检查过IB中面板的“可见发射”框的经典案例。把它关掉。

答案 1 :(得分:2)

是的,只要您希望它继续运行,您就需要拥有此控制器。你不能只是创造它,自动释放它,让它死掉 - 只要你需要它就需要保持它。

答案 2 :(得分:1)

不要忘记,如果您尝试将其作为“模态”表单运行(即,在用户解除它之前接管应用程序),您将需要推送新的运行循环。

你所做的是显示工作表,然后没有推出新的循环,所以操作系统只显示工作表,看到没有理由让它继续运行,从而将其关闭并在下一行继续执行:

我通常按以下方式填写表格:

- (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;
}

然后,在您的接受和/或取消按钮例程中:

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

}

我确信这样做的代码稍微少一些,但我并没有深入研究它,因为到目前为止,这种方式完全正常....

关于控制器和面板对象的生命周期的先前评论也是相关的 - 确保在显示模态面板时确切了解生命周期所需的对象。