如何重新从xib中载入NSWindow?

2011-11-20 20:05:38 +08:00
 keakon
我在IB中把一个NSWindow绑定到NSWindowController的window outlet上,然后用这种方式初始化:
if (!preferenceController) {
preferenceController = [[PreferenceController alloc] initWithWindowNibName:@"Preference"];
}
[preferenceController showWindow:self];

为了节省内存,我在窗口关闭时就设置了preferenceController.window = nil。之后再想显示时,不知道怎么载入这个window了…难道要重新创建一个controller?

另外,一旦这个窗口在后台,或者关闭过一次后,无论是showWindow:还是makeKeyAndOrderFront:都没法让窗口显示到前台,这是怎么回事?
现在只发现改成NSPanel,并把style设为Utility Panel可以让它一直显示在前台…
9186 次点击
所在节点    iDev
10 条回复
chenluois
2011-11-21 10:57:26 +08:00
居然没有人回答,那么我来答好了。

你的第一个问题:

首先,在你的 PreferenceController.m 的 init 里这样写

- (id)init
{
if (![super initWithWindowNibName:@"Preference"]) {
return nil;
}
return self;
}

其次,执行 action 显示窗口的时候就不要再用 initWithWindowNibName 了

if (!preferenceController) {
preferenceController = [[PreferenceController alloc] init];
}
[preferenceController showWindow:self];

最后,别忘了把 Preference.xib 的 File's Owner 的 Class 设置为 PreferenceController

这样设置下来,你的第二个问题也应该解决了。

再说你的第三个疑问:

为什么把 NSPanel 的 style 设为 Utility Panel 就可以让这个窗口一直显示在前台。这实际上就相当于加了一个 NSFloatingWindowLevel 的属性。
Level 这个概念有点儿类似图层,不同种类的窗口在不同的层上。一般窗口处于 NSNormalWindowLevel。NSFloatingWindowLevel 在 NSNormalWindowLevel 的上层。Dock 栏处于 NSDockWindowLevel,又在 NSFloatingWindowLevel 的上层。

一共有10个不同的层级:
NSNormalWindowLevel
NSFloatingWindowLevel
NSSubmenuWindowLevel
NSTornOffMenuWindowLevel
NSMainMenuWindowLevel
NSStatusWindowLevel
NSModalPanelWindowLevel
NSPopUpMenuWindowLevel
NSScreenSaverWindowLevel
NSDockWindowLevel


不设置 style 一样可以达到这样的效果,对任意一种类型的窗口应用 setLevel 方法即可,如:
[window setLevel:NSFloatingWindowLevel];
keakon
2011-11-21 11:22:37 +08:00
@chenluois 谢谢解答

第一个感觉执行的逻辑也没变,回家试试有什么不同吧…我怀疑是不是要用NSBundle + loadNibNamed:owner:

第二个我设置了File's Owner的Class,应该不是这个的问题。

第三个其实不是问题,只是我的窗口老不跑到前台来,才这样做的=。=
chenluois
2011-11-21 13:11:22 +08:00
虽然开头你已经说了 “我在IB中把一个NSWindow绑定到NSWindowController的window outlet上”,但我建议你回家后最好再检查确认下 window outlet 是否真的连接到了那个 NSWindow. :)
keakon
2011-11-21 13:33:22 +08:00
@chenluois 确实连了,没连之前controller的window属性都是nil,而且窗口关闭后就无法再显示了
chenluois
2011-11-21 13:35:16 +08:00
@keakon 哦,奇怪啊。:)
chenluois
2011-11-21 20:31:59 +08:00
@keakon 试了没有?问题解决了没?:)
keakon
2011-11-22 00:18:14 +08:00
@chenluois 改了后变成:如果窗口是关闭的,那么就能显示到前台;如果还没关闭,那就仍然保持在后台…
chenluois
2011-11-22 08:11:46 +08:00
@keakon 总算进了一步,这回在加个makeKeyAndOrderFront试试。
keakon
2011-11-22 10:31:11 +08:00
@chenluois 加了,没用=。=
chenluois
2011-11-22 10:37:57 +08:00
@keakon 诡异~ 另外诡异的是,为什么只有我一个人回答楼主的问题呢。期待高手作答。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/21806

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX