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