如何在使用Grand Central Dispatch处理某些内容时以模态方式正确显示"进度"表?

Rob*_*ert 11 cocoa objective-c grand-central-dispatch

我正在尝试在包含单个进度条的窗口上显示工作表,以显示使用Grand Central Dispatch异步运行的某些长函数的进度.我几乎得到了它,但是不能让表格看起来像是焦点,可能是因为我没有使用runModalForWindow:或类似.

这大概就是我现在正在做的事情,它发生在主窗口按下按钮的结果:

    // Prepare sheet and show it...

    [NSApp beginSheet:progressSheet modalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL];

    [progressSheet makeKeyAndOrderFront:self];

    [progressBar setIndeterminate:NO];
    [progressBar setDoubleValue:0.f];
    [progressBar startAnimation:self];


    // Start computation using GCD...

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        for (int i = 0; i < 1000; i ++) {
            // Do some large computation here
            // ...

            // Update the progress bar which is in the sheet:
            dispatch_async(dispatch_get_main_queue(), ^{
                [progressBar setDoubleValue:(double)i];
            });
        }


        // Calculation finished, remove sheet on main thread

        dispatch_async(dispatch_get_main_queue(), ^{
            [progressBar setIndeterminate:YES];

            [NSApp endSheet:progressSheet];
            [progressSheet orderOut:self];
        });
    });
Run Code Online (Sandbox Code Playgroud)

这是有效的,除了主窗口仍处于焦点,工作表失焦,并且进度条没有动画(除非我使用setUsesThreadedAnimation:YES它).

我认为我遇到的问题是,在开始异步计算之前,我不确定如何在不阻塞主线程的情况下以模态方式运行工作表?

小智 2

我有完全相同的问题。经过一些尝试和错误,我找到了解决方案。确保您的工作表窗口是 (a) NSWindow 而不是 NSPanel(这可能无关紧要),并且该窗口具有标题栏(因为它是您正在使用的工作表)不会显示。

由于这个原因,我关闭了标题栏,但不知何故,它需要正确获得焦点。勾选“标题栏”复选框可使我的进度栏工作表获得焦点。