V2EX 首页   注册   登入
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请 登入
iOS 开发实用技术导航
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Cocoa with Love
http://cocoawithlove.com/
iOS 开发实用书单
iPhone App Development: The Missing Manual
Cocoa and Objective-C: Up and Running
Cocoa Programming for Mac OS X
深入浅出设计模式 Head First Design Patterns
Useful Tools
Charles Web Debugging Proxy
Sponsored by
唐茶 字节社
中文世界最好的电子书城
V2EX  ›  iDev

如何重新从xib中载入NSWindow?

By keakon at 185 天前, 1423 次点击
我在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可以让它一直显示在前台…
10 回复  |  直到 2011-11-23 10:37:57 AM
    1
chenluois   185 天前
居然没有人回答,那么我来答好了。

你的第一个问题:

首先,在你的 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];
    2
keakon   185 天前
@chenluois 谢谢解答

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

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

第三个其实不是问题,只是我的窗口老不跑到前台来,才这样做的=。=
    3
chenluois   184 天前
虽然开头你已经说了 “我在IB中把一个NSWindow绑定到NSWindowController的window outlet上”,但我建议你回家后最好再检查确认下 window outlet 是否真的连接到了那个 NSWindow. :)
    4
keakon   184 天前
@chenluois 确实连了,没连之前controller的window属性都是nil,而且窗口关闭后就无法再显示了
    5
chenluois   184 天前
@keakon 哦,奇怪啊。:)
    6
chenluois   184 天前
@keakon 试了没有?问题解决了没?:)
    7
keakon   184 天前
@chenluois 改了后变成:如果窗口是关闭的,那么就能显示到前台;如果还没关闭,那就仍然保持在后台…
    8
chenluois   184 天前
@keakon 总算进了一步,这回在加个makeKeyAndOrderFront试试。
    9
keakon   184 天前
@chenluois 加了,没用=。=
    10
chenluois   184 天前
@keakon 诡异~ 另外诡异的是,为什么只有我一个人回答楼主的问题呢。期待高手作答。
Linode
关于   |   FAQ   |   我们的愿景   |   广告投放   |   工作空间   |   Gadget Lab   |   博客   |   上网首页   |   300 人在线   最高记录 362
创意工作者们的社区
Lovingly made by OLIVIDA
VERSION: 3.0.0-dev
♥ Do have a faith in what you're doing.