(Cocoa)在单窗口Cocoa应用程序中,UIViewController子类的等效物是什么?

9
在使用iOS应用程序后,我想尝试编写Cocoa应用程序,认为它们非常相似。因此,我有一个带有分割视图和一些NSTableView(类似于iTunes)的单窗口应用程序,并且正在寻找一个可以放置从Web获取数据以填充表格的代码的位置。
在iOS中,我会将其放置在适当的UIViewController子类的viewDidLoad方法中。然后,UITableViewDataSource将访问此数据以填充其单元格。
现在我有一个NSWindow,我可以做类似的事情,但是我该如何为其创建NSWindowController?这是否是我想要的?我可以将其放在AppDelegate中,但似乎不太合适。
1个回答

10
iOS和OS X的区别在于iOS中只有一个窗口,而OS X中可以有多个窗口。在OS X中,NSViewControllerUIViewController的工作方式不同,NSViewController设计用于加载和处理单个视图,而UIViewController似乎处理多个视图并提供更多的视图之间的黏合剂。即使是Apple文档也写道:

 

在Mac OS X中,AppKit视图控制器是窗口控制器的助手,后者最终负责窗口中的所有内容。

因此,在OS X中,UIViewController的对应物不是NSViewController,而是NSWindowController,它通过管理单个窗口及其视图内的布局/内容/交互,在OS X上提供了类似于UIViewController为iOS提供的功能。
在这种情况下,我会使用NSWindowController - 虽然如果应用程序非常简单,也可以使用App Delegate; 如果应用程序非常复杂,则使用NSViewController拆分代码不是坏主意。
使用NSWindowController的最佳方法是在App Delegate中使用[[CustomWindowController alloc] init]进行编程加载。
@implementation CustomWindowController
- (id)init
{
    self=[super initWithWindowNibName:@"CustomWindowNibName"];
    if(self)
    {
        //perform any initializations
    }
    return self;
}
@end

或者调用

[[CustomWindowController alloc] initWithWindowNibName:@"CustomWindowNibName"];

如果你想让NSWindowController可重用,你可以直接使用initWithWindowNibName来覆盖它。

你可以在MainMenu.xib文件中删除默认的窗口。


通常情况下,NSWindowController管理在其自己的nib文件中实例化的窗口。 NSWindowController通常拥有该nib文件。(尽管有可能使其管理以编程方式创建的窗口,但通常不是这样做的。)

因此,要能够使用自定义NSWindowController,您需要在单独的nib / xib文件中制作要管理的窗口。(使用默认的xib文件意味着您允许Cocoa自动实例化一个NSWindowController而没有机会进行子类化;您不能使用自定义NSWindowController与默认的NSMainNibFile。对于简单的应用程序,只需将所有控制器代码放在NSApplication/App Delegate中即可)

在至少Xcode 4中,这个过程涉及创建一个具有窗口模板和自定义NSWindowController类的xib,根据那个nib实例化基于CustomWindowController类,在-init或其他位置调用[CustomWindowController showWindow:self];(如果这样不起作用,则使用-makeKeyAndOrderFront:)来显示窗口(在-(void)applicationDid/WillFinishLaunching:(NSNotification *)aNotification 中可能是一个很好的地方)。

要停止默认窗口显示,我只需删除它。可能有更好的方法,但我不知道。


是的,我想我需要使用NSWindowController,但我不确定如何将其连接到NSWindow。我将一个新窗口拖入MainMenu.xib并进行设置,但当我运行应用程序时它已经被加载了。我还尝试使用AppDelegate来启动一些东西,但我不知道如何让我的NSTableView在AppDelegate.m中查找NSTableViewDataSource原型方法。我尝试从表格连接到“文件所有者”,并选择数据源,但它会出现错误“无效的NSTable视图数据源”。 - TijuanaKez
连接NSWindowController的最简单方法是拆分你的nib文件并为其提供自己的文件进行加载。因此,使用窗口模板创建一个新的nib文件,并将Files Owner设置为控制器。另外,关于你尝试连接dataSource的问题:在那种情况下,“File's Owner”是NSApplication;你应该拖到App Delegate上。 - Vervious
好的,我创建了一个新的控制器'MainWindowController'并勾选了'with xib file'。我从MainMenu.xip中复制了NSwindow并将其粘贴到新的MainWindowController.xib文件中,删除了旧的窗口。File's Owner的'Custom Class'设置为MainWindowController。我在MainWindowController.m中添加了自定义init方法,其中包括self=[super initWithWindowNibName:@"MainWindowController"];。我在应用程序委托的applicationDidFinishLaunching方法中实例化了我的MainWindowController属性,使用mainWindow = [[MainWindowController alloc] init];。没有错误,但是没有窗口。我有什么遗漏的吗? - TijuanaKez
在应用程序委托的applicationDidFinishLaunching:方法中,在[[CustomWindowController alloc] initWithWindowNibName:@"CustomWindowNibName"];之后,[CustomWindowController showWindow:self];可以工作,但[CustomWindowController.window makeKeyAndOrderFront:nil]无法工作。 - TijuanaKez
@TijuanaKez 太棒了!我对 -makeKeyAndOrderFront: 的理解有误,但很高兴你找到了正确的解决方案。 - Vervious

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