7

我正在尝试将 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消息)。床单永远不会挂在窗户上。

如果有人能指出我在哪里可以找到更多信息,那将不胜感激。

4

3 回答 3

17

这听起来像是为 IB 中的面板选中“启动时可见”框的经典案例。把它关掉。

于 2009-09-22T09:28:56.873 回答
2

是的,只要您希望它继续运行,您就需要拥有此控制器。你不能只是创建它,自动释放它,然后让它死掉——你需要一直持有它,只要你需要它。

于 2009-09-22T02:31:09.497 回答
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];

}

我敢肯定有一种稍微少一点代码的方式来做这件事,但我没有深入研究它,因为到目前为止这种方式工作得很好......

先前关于控制器和面板对象的生命周期的评论也很重要——在显示模态面板时,请务必准确了解您需要哪些对象来实现哪些生命周期。

于 2009-09-22T16:24:31.637 回答