4

我的目标:当应用程序通过一个冗长的循环运行时,显示一个具有确定 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 吗?预先感谢您的帮助!

4

2 回答 2

15

发现这个宝石做一些谷歌搜索。Interface Builder 中我的 NSPanel 的行为设置为“Visible at Launch”,这是使用 IB 时新窗口的默认设置。发生的事情是,一旦加载了笔尖,窗口就在 BEFORE 可见[NSApp beginSheet:...]。因此,取消选中“启动时可见”选项解决了我的问题,现在出现了一个工作表,连接到我想要的窗口。

于 2010-11-03T20:25:57.973 回答
1
@implementation ProgressSheetController //subclass of NSPanel

-(void)showProgressSheet:(NSWindow *)window
{
    //progressPanel is an IBOutlet to the NSPanel
    if(!progressPanel)
        [NSBundle loadNibNamed:@"ProgressPanel" owner:self];

所以你的 NSPanel 拥有另一个 NSPanel?如果第二个是进度面板,第一个显示什么?

我应该改为 [子类] NSWindowController 吗?

听起来像。

modalSession = [NSApp beginModalSessionForWindow:progressPanel];

为什么?

[modalProgressSheet showProgressSheet:[NSApp mainWindow]];

您是否确认有一个主窗口?mainWindow不返回你最关心的窗口;它返回活动窗口(可能但不一定也是关键)。

如果mainWindow正在返回nil,那可能是您的问题的原因。

int i,
for(i=0; i<count; i++)
{
    //do some stuff with the object at index i in the filesToTest array

首先,int是错误的类型。您应该使用NSUIntegerNSArray 索引。

其次,除非您需要其他索引,否则您应该使用快速枚举

于 2010-11-01T19:51:48.323 回答