Estoy tratando de mostrar una hoja en una ventana que contiene una única barra de progreso, para mostrar el progreso de una función larga que se ejecuta de forma asíncrona utilizando Grand Central Dispatch. Casi lo tengo, pero no puedo hacer que la hoja parezca estar enfocada, probablemente porque no he usado runModalForWindow:
o similar.¿Cómo mostrar correctamente una hoja de "progreso" modalmente mientras se usa Grand Central Dispatch para procesar algo?
Esto es aproximadamente lo que estoy haciendo en este momento, que sucede como resultado de una pulsación de botón en la ventana principal:
// 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];
});
});
Esto funciona, excepto la ventana principal se encuentra todavía en el enfoque, la la hoja está fuera de foco, y la barra de progreso no se anima (a menos que use setUsesThreadedAnimation:YES
en ella).
El problema que creo que tengo es que no estoy seguro de cómo ejecutar la hoja modalmente sin bloquear el hilo principal antes de iniciar el cálculo asincrónico.
La ejecución modal de la hoja para la ventana no debe bloquear el hilo principal (de lo contrario, nada después de que se ejecute el bit '-beginSheet:' al principio del método). Utilizo algo casi idéntico a esto (hoja modal presentada como lo hace, con una barra de progreso) en mi aplicación aquí, y se actualiza perfectamente desde un bloque GCD ejecutado en segundo plano. Los controles en la ventana por la que se desliza la hoja están en gris, lo que indica que la ventana ha perdido el foco en la hoja, por lo que parece normal también. ¿Podría haber algo más haciendo cola en muchas acciones en el hilo principal? –
@BradLarson La única otra cosa en la que podía pensar que podría estar causando problemas era un 'dispatch_apply' como parte del cómputo principal, pero reemplazarlo con un ciclo estándar no hizo ninguna diferencia. De lo contrario, no hay prácticamente nada más ejecutándose en el hilo principal. Todavía puedo interactuar principalmente con los controles en la ventana principal, detrás de la hoja, y aún aparecen en foco (es decir, no atenuados). Un cuadro de texto en la ventana principal, por ejemplo, mientras se muestra la hoja, aparece con un anillo de enfoque y aún puedo ingresar texto en él (aunque no puedo seleccionar texto con el mouse). – Robert