Я пытаюсь отобразить лист в окне, содержащем одну полосу выполнения, чтобы показать прогресс какой-то длинной функции, выполняющейся асинхронно с использованием 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];
});
});
Это работает, за исключением того, что главное окно все еще в фокусе, лист не в фокусе , и индикатор выполнения не анимируется (если я не использую для него setUsesThreadedAnimation: YES
).
Проблема, с которой я столкнулся, заключается в том, что я не знаю, как запустить лист модально, не блокируя основной поток, прежде чем я начну асинхронное вычисление?