8

NSAlert我有一个 Cocoa 应用程序,它使用该类显示应用程序模式警报。我希望警报窗口浮动在所有其他应用程序的窗口之上。这可以用 来完成NSAlert,还是我需要实现自己的窗口?

我不知道这些是否重要,但该应用程序是一个代理应用程序(LSUIElement是真的),实现为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 版本。如果你真的关心这种可能性,我会在上面提交一个错误。NSApplication 不支持 [[alert window] setLevel: someLevel] 是很奇怪的,而且为了能够做到这一点,必须使用其所有简洁的自动布局功能重新构建 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 回答