如何将 NSPanel 显示为工作表
我正在尝试将 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
消息)。床单永远不会挂在窗户上。
如果有人能指出我在哪里可以找到更多信息,那将非常感激。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这听起来像是在 IB 中选中面板的“启动时可见”框的经典案例。把它关掉。
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:
Then, in your accept and/or cancel button routines:
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.