macos 保持 NSWindow 前面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5364460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 07:51:09  来源:igfitidea点击:

Keep NSWindow front

macoscocoafocusnswindow

提问by user661577

I open a NSWindow from my main NSWindow.

我从我的主 NSWindow 打开一个 NSWindow。

DropHereWindowController *dropHereWindowController = [[DropHereWindowController alloc] initWithWindowNibName:@"DropHereWindow"];
[dropHereWindowController showWindow:nil];

I want this window to stay on top of my main window when dragging a file from the finder to that "DropHereWindow". However when opening the finder (not having the focus any longer) my "DropHereWindow" goes behind my main window.

将文件从查找器拖到“DropHereWindow”时,我希望此窗口位于主窗口的顶部。然而,当打开取景器(不再有焦点)时,我的“DropHereWindow”在我的主窗口后面。

I tried orderFront, makeKey, makeKeyAndFront but nothing helped. What can I do about it?

我尝试过 orderFront、makeKey、makeKeyAndFront 但没有任何帮助。我该怎么办?

回答by Anne

Method:

方法:

- (void)setLevel:(NSInteger)windowLevel

Sub-class the NSWindow:

子类 NSWindow:

[self setLevel: NSStatusWindowLevel];

Or simply use:

或者简单地使用:

[window setLevel: NSStatusWindowLevel];

Available levels:

可用级别:

  • NSNormalWindowLevel
  • NSFloatingWindowLevel
  • NSSubmenuWindowLevel
  • NSTornOffMenuWindowLevel
  • NSModalPanelWindowLevel
  • NSMainMenuWindowLevel
  • NSStatusWindowLevel
  • NSPopUpMenuWindowLevel
  • NSScreenSaverWindowLevel
  • kCGDesktopWindowLevel
  • NSNormalWindowLevel
  • NSFloatingWindowLevel
  • NSSubmenuWindowLevel
  • NSTornOffMenuWindowLevel
  • NSModalPanelWindowLevel
  • NSMainMenuWindowLevel
  • NSStatusWindowLevel
  • NSPopUpMenuWindowLevel
  • NSScreenSaverWindowLevel
  • kCGDesktopWindowLevel

回答by Peter Hosey

You say:

你说:

I tried orderFront, makeKey, makeKeyAndFront but nothing helped.

我尝试过 orderFront、makeKey、makeKeyAndFront 但没有任何帮助。

And then:

接着:

Method:

- (void)setLevel:(NSInteger)windowLevel

It doesn't work, the window still goes behind my main window when clicking on the finder icon.

方法:

- (void)setLevel:(NSInteger)windowLevel

它不起作用,当单击查找器图标时,窗口仍然在我的主窗口后面。

Then you're doing something wrong.

那么你做错了什么。

For one thing, a window shouldn't?automatically go behind another window anyway. Either you're (or the user is) ordering the main window front or you're ordering the other window back. I'll assume you're not doing the latter.

一方面,一个窗口不应该?自动地在另一个窗口后面。要么您(或用户)订购主窗口正面,要么您订购另一个窗口背面。我假设你不会做后者。

For another, orderFront:, makeKeyAndOrderFront:, and setLevel:do work. In particular, setLevel:puts the window on an entire other plane, so it will alwaysbe in front of (or behind, depending on the level you choose) windows with the default level, no matter what you do.

另一方面,orderFront:, makeKeyAndOrderFront:, 和setLevel:do work。特别是,setLevel:将窗口放在整个其他平面上,因此无论您做什么,它都将始终位于默认级别的窗口前面(或后面,取决于您选择的级别)。

I would guess that you have not hooked up, or you have accidentally disconnected, your windowoutlet to the window, which would mean you are sending your orderFront:/setLevel:messages to nil, which does nothing. Make sure your outlet is filled in at the point where you sendthe orderFront:or setLevel:message, by logging the window to the console. If it says “(null)” or “0x0” (depending on how you log it), then your outlet holds nil; check that it's hooked up in the nib and that you've already loaded the nib/instantiated the window controller.

我猜你还没有连接上,或者你不小心断开了你window到窗口的插座,这意味着你正在发送你的orderFront:/setLevel:消息nil,它什么都不做。确保电源插座填充在您发送点orderFront:setLevel:通过登录窗口的控制台消息。如果它显示“(null)”或“0x0”(取决于您的记录方式),则您的插座保持nil;检查它是否已连接到笔尖并且您已经加载笔尖/实例化了窗口控制器。

All that said, I disagree that setLevel:is the correct solution. If you just want to have one window stay in front of a specific other window, and not put it on an entire other plane, make it a child window.

尽管如此,我不同意这setLevel:是正确的解决方案。如果您只想让一个窗口停留在另一个特定窗口的前面,而不是将其放在整个其他平面上,请将其设为子窗口

回答by Jay Wong

Swift 4.0, Xcode 9.0

斯威夫特 4.0,Xcode 9.0

You can set the levelproperty of your NSWindowto floating. For example, if you are subclassing NSWindow, you can set it in the override init.

您可以将您的level属性设置NSWindowfloating. 例如,如果您是子类化NSWindow,则可以在覆盖 init 中设置它。

self.level = .floating

You also can get NSWindowfrom your NSWindowControllerby self.window?.

你也可以NSWindow从你的NSWindowControllerby self.window?.

There are different levels:

有不同的级别:

NSNormalWindowLevel

The default level for NSWindow objects.

NSFloatingWindowLevel

Useful for floating palettes.

NSSubmenuWindowLevel

Reserved for submenus. Synonymous with NSTornOffMenuWindowLevel, which is preferred.

NSTornOffMenuWindowLevel

The level for a torn-off menu. Synonymous with NSSubmenuWindowLevel.

NSModalPanelWindowLevel

The level for a modal panel.

NSMainMenuWindowLevel

Reserved for the application's main menu.

NSStatusWindowLevel

The level for a status window.

NSPopUpMenuWindowLevel

The level for a pop-up menu.

NSScreenSaverWindowLevel

The level for a screen saver.

NSNormalWindowLevel

NSWindow 对象的默认级别。

NSFloatingWindowLevel

对浮动调色板很有用。

NSSubmenuWindowLevel

为子菜单保留。与 NSTornOffMenuWindowLevel 同义,这是首选。

NSTornOffMenuWindowLevel

撕下菜单的级别。与 NSSubmenuWindowLevel 同义。

NSModalPanelWindowLevel

模态面板的级别。

NSMainMenuWindowLevel

为应用程序的主菜单保留。

NSStatusWindowLevel

状态窗口的级别。

NSPopUpMenuWindowLevel

弹出菜单的级别。

NSScreenSaverWindowLevel

屏幕保护程序的级别。

回答by Mrug

This one worked for me, hope that can be helpful

这个对我有用,希望能有所帮助

[self.window makeKeyAndOrderFront:nil];
[self.window setLevel:NSStatusWindowLevel];

回答by Daniel Storm

Using the CGWindowLevelKeykCGMaximumWindowLevelKeyalso works.

使用CGWindowLevelKeykCGMaximumWindowLevelKey也有效。

[window setLevel:CGWindowLevelForKey(kCGMaximumWindowLevelKey)];

CGWindowLevelKey Reference

CGWindowLevelKey 参考

回答by OlDor

NSStatusWindowLevelworks, just use it after some small delayafter starting the app (or after creating the window).

NSStatusWindowLevel工作,只需在启动应用程序后(或创建窗口后)一些小的延迟使用它

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
    self.view.window.level = NSStatusWindowLevel;
});