Pregunta

Tengo una aplicación Cocoa que muestra una alerta aplicación-modal mediante la clase NSAlert. Me gustaría que la ventana de alerta para flotar por encima de todas las ventanas de otras aplicaciones. ¿Es posible hacerlo con NSAlert, o necesito para poner en práctica mi propia ventana?

No sé si algo de esto importa, pero la aplicación es una aplicación de agente (LSUIElement es cierto) implementado como un NSStatusItem. (Para obtener más información sobre la aplicación, incluyendo el código fuente, busque .)

Este es el código que muestra la alerta:

- (void)showTimerExpiredAlert {
    [NSApp activateIgnoringOtherApps:YES];

    NSAlert *alert = [[NSAlert alloc] init];
    [alert setAlertStyle:NSInformationalAlertStyle];
    [alert setMessageText:NSLocalizedString(@"Menubar Countdown Complete", @"Expiration message")];
    [alert setInformativeText:NSLocalizedString(@"The countdown timer has reached 00:00:00.",
                                                @"Expiration information")];
    [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button title")];
    [alert addButtonWithTitle:NSLocalizedString(@"Restart Countdown...", @"Restart button title")];

    NSInteger clickedButton = [alert runModal];
    [alert release];

    if (clickedButton == NSAlertSecondButtonReturn) {
        // ...
    }
}

He intentado poner esto antes de la llamada runModal:

[[alert window] setFloatingPanel:YES];

También he intentado esto:

[[alert window] setLevel:NSFloatingWindowLevel];

Sin embargo, ninguno de los que hace que la estancia ventana por encima de los demás, si hago clic en la ventana de otra aplicación. Sospecho runModal simplemente no cumple ninguno de esos ajustes.

¿Fue útil?

Solución

Me destrocé mi cerebro acerca de esta cosa exacta hace un tiempo.

La única manera que podía conseguir que esto funcione (más o menos), fue subclase NSApplication, y anular -sendEvent. En -sendEvent, que le llama por primera vez la aplicación de súper, y luego hacer algo como esto:

id *modalWindow = [self modalWindow];
if (modalWindow && [modalWindow level] != MY_DESIRED_MODAL_WINDOW_LEVEL)
    [modalWindow setLevel: MY_DESIRED_MODAL_WINDOW_LEVEL];

Además de que incluso esto no funcionó bastante impecable - al cambiar de aplicaciones -. Usted nunca quiere hacer esto de todos modos porque es un truco flagrante, el crudo

Así que sí, por desgracia es mejor escribir su propia versión de NSAlert. Si realmente se preocupan por esta posibilidad, me presento un error en él. Es muy raro que [[ventana de alerta] setLevel: someLevel]. No es honrado por NSApplication y es un desperdicio tener que volver a construir NSAlert con toda su botoncito disposición automática características sólo para ser capaz de hacer esto

Otros consejos

Lo que terminé haciendo fue abandonando NSAlert y en su lugar se carga un NSWindow alertish de una SEMILLA.

Este es el código que se muestra la ventana:

- (void)showAlert {
    NSWindow *w = [self window];
    [w makeFirstResponder:nil];
    [w setLevel:NSFloatingWindowLevel];
    [w center];
    [w makeKeyAndOrderFront:self];
}

Con ello se pretende hacerlo actuar como una alerta, excepto que también flota, y que no es modal, por lo que los elementos de menú se pueden seleccionar mientras está activado.

¿Hay algo más que debería haber hecho?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top