在 Cocoa 中使用自定义模态表时出现问题

发布于 2024-09-30 07:56:24 字数 1988 浏览 3 评论 0原文

我的目标:当应用程序通过一个漫长的循环运行时,显示具有确定 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

季末如歌 2024-10-07 07:56:24

通过谷歌搜索发现这个宝石。 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.

初心 2024-10-07 07:56:24
@implementation ProgressSheetController //NSPanel 的子类

-(void)showProgressSheet:(NSWindow *)窗口
{
    //progressPanel 是 NSPanel 的 IBOutlet
    if(!progressPanel)
        [NSBundle loadNibNamed:@"ProgressPanel" 所有者:self];

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

我应该[子类化] NSWindowController 吗?

听起来是这样。

modalSession = [NSApp beginModalSessionForWindow:progressPanel];

为什么?

[modalProgressSheet showProgressSheet:[NSApp mainWindow]];

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

如果 mainWindow 返回 nil,这可能是导致问题的原因。

int i,
for(i=0; i<计数; i++)
{
    //对filesToTest数组中索引i处的对象做一些事情

首先,int 是错误的类型。您应该使用 NSUInteger 作为 NSArray 索引。

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

@implementation ProgressSheetController //subclass of NSPanel

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

So your NSPanel owns another NSPanel? If the second one is the progress panel, what does the first one show?

Should I [subclass] NSWindowController instead?

Sounds like it.

modalSession = [NSApp beginModalSessionForWindow:progressPanel];

Why?

[modalProgressSheet showProgressSheet:[NSApp mainWindow]];

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 returning nil, that could be the cause of your problem.

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

First, int is the wrong type. You should use NSUInteger for NSArray indexes.

Second, unless you need the index for something else, you should use fast enumeration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文