NSWindow的makeKeyAndOrderFront方法让窗口出现,但不会成为键盘焦点或前置窗口。

27

makeKeyAndOrderFront无法将我的NSWindow设置为key或front。

我的应用没有主窗口或菜单栏,这可能是问题的一部分?

IBOutlet NSWindow *loginWindow;
//(connected in Interface Builder to the NSWindow)
NSWindow的“visible at launch”和“release when closed”都未被选中。 然后:
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [loginWindow makeKeyAndOrderFront:self];
}

这个确实打开了窗口。(将其注释会导致不打开窗口。)

但是:

  • 它出现在Xcode窗口后面(而不是前面)。

  • 它似乎接收到鼠标焦点,但无法在文本字段中接受按键输入。按键被发送到Xcode。

  • 当激活Expose时,它出现在Expose网格中。但我无法点击窗口选择它在Expose中...它不会到前面。

为什么我的窗口没用?


3
应用程序不需要拥有“主窗口”,或者根本不需要任何特定于应用程序的窗口,也不需要主菜单(尽管它们总是应该有一个主菜单——这样可以免费获得很多关键命令,即使应用程序不使用菜单栏)。在Cocoa术语中,具有活动外观的窗口是主窗口;更重要的是,一个应用程序没有窗口是完全有效的,这由每个基于文档的应用程序、仅后台应用程序和UI元素所证明。 - Peter Hosey
3个回答

37
尝试调用此方法[NSApp activateIgnoringOtherApps:YES];,这应该使其成为活动应用程序。

我需要精确翻译您的内容吗?还是说我需要将“NSApp”替换为变量?如果直接复制到“makeKeyAndOrderFront”行之前,不会有任何变化。与我上面描述的行为完全相同。 - ck_
@cksubs:NSApp是一个变量,你不需要改变它。这应该解决你的直接问题(应用程序不在最前面),但不应该是必要的(应用程序应该自动成为Xcode启动的一部分)。 - Peter Hosey
3
我确实最终需要使用activateIgnoringOtherApps命令,除了将LSUIElement添加到Info.plist之外。 - ck_
我认为你不应该使用这种方法,因为微软拥有侵入式弹出窗口的专利。"通过弹出窗口窃取用户焦点的方法",因此Mac应用程序不使用此功能,而且更加内向。 - Michael

34

猜测:您在Info.plist文件中设置了LSBackgroundOnly。这是造成此问题的原因:只有后台应用程序不能切换到前台,这就是为什么您的窗口无法切换到前台的原因。

如果您希望您的应用程序不出现在Dock中,请使用LSUIElement替代。这将抑制您的应用程序的Dock图标,并使其不显示自己的菜单栏主菜单,但保留其使窗口最前并使其成为关键窗口的能力。


没错,LSUIElement 可以解决这个问题。我之前使用的是 NSBGOnly,但似乎现在已被弃用。 - ck_
2
@cksubs:是的:NSBGOnly已更名为LSBackgroundOnly。只有旧名称被弃用;LSUIElementLSBackgroundOnly都是当前的,但执行不同的操作。它们以及所有其他当前密钥都在“信息属性列表密钥参考”中进行了记录:http://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/ - Peter Hosey

8
这两个答案都是正确的。如果窗口是无边框的,您还需要确保在窗口子类中覆盖canBecomeKey方法。
我花了很长时间才弄明白这个问题。(我写了一篇关于整个解决方案的博客文章。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接