8

NSAlertクラスを使用してアプリケーションモーダルアラートを表示するCocoaアプリケーションがあります。アラートウィンドウを他のすべてのアプリケーションのウィンドウの上に表示したいのですが。これはで実行できますNSAlertか、それとも独自のウィンドウを実装する必要がありますか?

これが重要かどうかはわかりませんが、アプリケーションはLSUIElementとして実装されたエージェントアプリケーション(true)NSStatusItemです。(ソースコードなど、アプリの詳細については、<こちら>をご覧ください。)

アラートを表示するコードは次のとおりです。

- (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) {
        // ...
    }
}

私はこれをrunModal電話の前に置いてみました:

[[alert window] setFloatingPanel:YES];

私もこれを試しました:

[[alert window] setLevel:NSFloatingWindowLevel];

ただし、別のアプリケーションのウィンドウをクリックしても、ウィンドウが他のウィンドウの上に表示されることはありません。私runModalはこれらの設定のどちらも尊重していないのではないかと思います。

4

2 に答える 2

5

私は少し前にこの正確なことについて頭を悩ませました。

これを機能させる唯一の方法(一種)は、NSApplicationをサブクラス化し、-sendEventをオーバーライドすることでした。-sendEventでは、最初にsuperの実装を呼び出してから、次のようにします。

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

それを除けば、これでさえ完全に機能しませんでした–アプリを切り替えるとき–それは露骨で粗雑なハックなので、とにかくこれをしたくはありません。

そうです、悲しいことに、NSAlertの独自のバージョンを作成する方が良いでしょう。この可能性を本当に気にかけているのなら、バグを報告します。[[alert window] setLevel:someLevel]がNSApplicationによって尊重されないのはかなり奇妙なことであり、これを実行できるようにするためだけに、NSAlertをすべてのすてきな小さな自動レイアウト機能で再構築する必要があるのは無駄です。

于 2009-04-19T23:23:30.803 に答える
2

私がやったことは放棄することNSAlertであり、代わりに私NSWindowはNIBからアラートをロードします。

ウィンドウを表示するコードは次のとおりです。

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

これは、アラートのように動作させることを目的としていますが、フローティングであり、モーダルではないため、メニュー項目は起動中に選択できます。

他にやるべきことはありますか?

于 2009-04-21T02:03:36.557 に答える