如何为基于Xib而非Storyboard的应用创建/添加NSWindowController?
嘿,这个场景我太熟悉了!很多用Xib起步的Mac应用都会碰到这个问题,我来一步步带你搞定添加NSWindowController的流程,保证清晰易懂:
步骤1:创建NSWindowController子类
- 打开Xcode,右键点击你的项目目录,选择「New File...」
- 在弹出的模板选择框里,选「Cocoa Class」然后点击Next
- 给你的控制器起个名字(比如
MainWindowController就很直观),父类选择NSWindowController,一定要注意不要勾选「Also create XIB file for user interface」——毕竟咱们已经有Main.xib了,不需要额外生成新的Xib文件,最后点击Create完成创建。
步骤2:把Main.xib和WindowController关联起来
- 打开
Main.xib,在左侧的Document Outline面板里选中「File's Owner」 - 打开右侧的Identity Inspector(就是那个带身份证图标的面板),在Class下拉菜单里选择你刚创建的
MainWindowController - 接下来绑定window属性:按住Control键,从File's Owner拖到Xib里的NSWindow组件上,松开鼠标后在弹出的菜单里选择「window」——这一步就把控制器的window属性和Xib里的实际窗口绑定在了一起。
步骤3:修改AppDelegate来加载WindowController
- 打开你的
AppDelegate.swift(如果是Objective-C项目就打开AppDelegate.m) - 首先在类里添加一个属性来持有windowController,避免它被提前释放:
Objective-C版本的话,先在头文件里声明:// Swift版本 private var mainWindowController: MainWindowController!@property (strong, nonatomic) MainWindowController *mainWindowController; - 然后找到
applicationDidFinishLaunching方法,替换掉原来的窗口加载逻辑(如果有的话),改成初始化并显示windowController:
Swift版本代码:
Objective-C版本代码:func applicationDidFinishLaunching(_ aNotification: Notification) { // 用Main.xib作为资源初始化windowController mainWindowController = MainWindowController(windowNibName: NSNib.Name("Main")) // 显示窗口 mainWindowController.showWindow(nil) }- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { self.mainWindowController = [[MainWindowController alloc] initWithWindowNibName:@"Main"]; [self.mainWindowController showWindow:nil]; } - 小提醒:如果原来的AppDelegate里有
window属性,现在可以删掉它了——因为窗口的管理已经交给NSWindowController,AppDelegate不再需要持有窗口实例。
步骤4:验证并扩展功能
- 现在你可以在
MainWindowController里添加各种窗口相关的逻辑了,比如处理windowDidLoad生命周期事件、绑定控件的点击事件等等,所有窗口相关的逻辑都应该放在这里,符合MVC的设计原则。 - 运行应用,窗口应该正常显示,而且你可以在WindowController里轻松管理窗口的状态和行为了。
内容的提问来源于stack exchange,提问作者Mark A. Donohoe
相关产品推荐
相关产品推荐

