我有一个Cocoa应用程序,它使用NSAlert
类显示应用程序模式警报。我希望警报窗口浮动在所有其他应用程序的窗口之上。可以使用NSAlert
完成,还是需要实现自己的窗口?
我不知道这是否重要,但应用程序是一个代理应用程序(LSUIElement
为真),实现为NSStatusItem
。 (有关该应用的更多信息,包括源代码,请查看<here>。)
以下是显示警报的代码:
- (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
只是不尊重这些设置。
答案 0 :(得分: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,这是浪费。
答案 1 :(得分:2)
我最终做的是放弃NSAlert
,而是从NIB加载警告NSWindow
。
以下是显示窗口的代码:
- (void)showAlert {
NSWindow *w = [self window];
[w makeFirstResponder:nil];
[w setLevel:NSFloatingWindowLevel];
[w center];
[w makeKeyAndOrderFront:self];
}
这是为了使它像一个警报,除了它也浮动,它不是模态的,所以菜单项可以在它启动时选择。
还有什么我应该做的吗?