在 Cocoa 中使用自定义模态表时出现问题
我的目标:当应用程序通过一个漫长的循环运行时,显示具有确定 NSProgressIndicator 的自定义工作表。我希望工作表是应用程序模式,而不是文档模式。用户无法关闭模式表。他们必须等待应用程序完成循环处理。
问题:我无法将自定义工作表附加到窗口。它显示为一个单独的窗口,缺少窗口标题栏(工作表应该如此)。此外,当循环结束时,片材不会被释放(不会关闭)。
我有 2 个单独的 nib 文件用于工作表和主应用程序窗口,每个窗口还有 2 个控制器类。
以下是相关信息: 自定义工作表的控制器实现:
@implementation ProgressSheetController //subclass of NSPanel
-(void)showProgressSheet:(NSWindow *)window
{
//progressPanel is an IBOutlet to the NSPanel
if(!progressPanel)
[NSBundle loadNibNamed:@"ProgressPanel" owner:self];
[NSApp beginSheet: progressPanel
modalForWindow: window
modalDelegate: nil
didEndSelector: nil
contextInfo: nil];
//modalSession is an instance variable
modalSession = [NSApp beginModalSessionForWindow:progressPanel];
[NSApp runModalSession:modalSession];
}
-(void)removeProgressSheet
{
[NSApp endModalSession:modalSession];
[NSApp endSheet:progressPanel];
[progressPanel orderOut:nil];
}
//some other methods
@end
主应用程序窗口的实现。 testFiles 方法是连接到按钮的 IBAction。
@implementation MainWindowViewController //subclass of NSObject
-(IBAction)testFiles:(id)sender;
{
//filesToTest is a mutable array instance variable
int count = [filesToTest count];
float progressIncrement = 100.0 / count;
ProgressSheetController *modalProgressSheet = [[ProgressSheetController alloc] init];
[modalProgressSheet showProgressSheet:[NSApp mainWindow]];
int i,
for(i=0; i<count; i++)
{
//do some stuff with the object at index i in the filesToTest array
//this method I didn't show in ProgressSheetController.m but I think it's self explanatory
[modalProgressSheet incrementProgressBarBy:progressIncrement];
}
//tear down the custom progress sheet
[modalProgressSheet removeProgressSheet];
[modalProgressSheet release];
}
@end
一个想法:我的子类化是否正确?我应该使用 NSWindowController 吗?预先感谢您的帮助!
My objective: Display a custom sheet with a determinate NSProgressIndicator while the app works through a lengthy loop. I want the sheet to be application-modal, not document-modal. The user cannot dismiss the modal sheet. They must wait for the app to finish processing the loop.
Problem: I can't get the custom sheet to attach to the window. It appears as a separate window lacking the window title bar (as a sheet should). Additionally, the sheet is not released (does not close) when the loop finishes.
I have 2 separate nib files for the sheet and main application window, and also 2 controller classes for each window.
Here's the pertinent information:
Controller implementation for the custom sheet:
@implementation ProgressSheetController //subclass of NSPanel
-(void)showProgressSheet:(NSWindow *)window
{
//progressPanel is an IBOutlet to the NSPanel
if(!progressPanel)
[NSBundle loadNibNamed:@"ProgressPanel" owner:self];
[NSApp beginSheet: progressPanel
modalForWindow: window
modalDelegate: nil
didEndSelector: nil
contextInfo: nil];
//modalSession is an instance variable
modalSession = [NSApp beginModalSessionForWindow:progressPanel];
[NSApp runModalSession:modalSession];
}
-(void)removeProgressSheet
{
[NSApp endModalSession:modalSession];
[NSApp endSheet:progressPanel];
[progressPanel orderOut:nil];
}
//some other methods
@end
Implementation for the main application window. testFiles method is an IBAction connected to a button.
@implementation MainWindowViewController //subclass of NSObject
-(IBAction)testFiles:(id)sender;
{
//filesToTest is a mutable array instance variable
int count = [filesToTest count];
float progressIncrement = 100.0 / count;
ProgressSheetController *modalProgressSheet = [[ProgressSheetController alloc] init];
[modalProgressSheet showProgressSheet:[NSApp mainWindow]];
int i,
for(i=0; i<count; i++)
{
//do some stuff with the object at index i in the filesToTest array
//this method I didn't show in ProgressSheetController.m but I think it's self explanatory
[modalProgressSheet incrementProgressBarBy:progressIncrement];
}
//tear down the custom progress sheet
[modalProgressSheet removeProgressSheet];
[modalProgressSheet release];
}
@end
One thought: Am I subclassing correctly? Should I use NSWindowController instead? Thank you in advance for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过谷歌搜索发现这个宝石。 Interface Builder 中 NSPanel 的行为设置为“启动时可见”,这是使用 IB 时新窗口的默认行为。发生的情况是,一旦笔尖加载,窗口就会在
[NSApp beginSheet:...]
之前可见。因此,取消选中“启动时可见”选项解决了我的问题,现在一张工作表出现连接到我想要的窗口。Found this gem doing some googling. The behavior for my NSPanel in Interface Builder was set to "Visible at Launch" which is the default for new windows when using IB. What happened was as soon as the nib was loaded, the window was made visible BEFORE
[NSApp beginSheet:...]
. Therefore, unchecking the "Visible at Launch" option solved my problem and now a sheet appears connected to the window like I want.那么你的 NSPanel 拥有另一个 NSPanel 吗?如果第二个是进度面板,那么第一个显示什么?
听起来是这样。
为什么?
您确认有主窗口吗?
mainWindow
不会返回你最关心的窗口;它返回活动窗口(这可能但不一定也是关键)。如果
mainWindow
返回nil
,这可能是导致问题的原因。首先,
int
是错误的类型。您应该使用NSUInteger
作为 NSArray 索引。其次,除非您需要其他索引,否则应该使用 快速枚举。
So your NSPanel owns another NSPanel? If the second one is the progress panel, what does the first one show?
Sounds like it.
Why?
Have you verified that there is a main window?
mainWindow
does not return the window you care most about; it returns the active window (which is probably, but not necessarily, also key).If
mainWindow
is returningnil
, that could be the cause of your problem.First,
int
is the wrong type. You should useNSUInteger
for NSArray indexes.Second, unless you need the index for something else, you should use fast enumeration.