在基于文档的OS X应用程序

时间:2015-06-11 15:02:15

标签: objective-c cocoa nsdocument nsviewcontroller

我正在开发一个简单的OS X Cocoa应用程序,其中用户填写表单,应用程序执行一些在其他字段中弹出的计算。

我从Xcode 6.3.2(Yosemite)上的默认基于文档的应用程序模板开始。该模板包含NSDocument的子类和NSViewController的子类。界面在Storyboard中定义。 NSDocument从makeWindowControllers中的Storyboard初始化接口。

我遇到了将界面的各个部分绑定到ViewController的代表对象的问题 - 事实证明我绑定到了nil。永远不会调用ViewController的setRepresentedObject方法。

我尝试在viewDidLoad中调用ViewController调用setRepresentedObject,但是WindowController的文档属性在那时没有设置(它返回了nil)。

我不清楚是否有可能从NSDocument获取ViewController的实例 - NSDocument知道它的窗口/ WindowController,但我不知道如何从这些类中找到一个ViewController。

我想了解惯用的Xcode / Apple方法。无论是通过Storyboard视图还是以我的代码中的编程方式。

如果可能的话,我还想避免过于紧密地耦合代码。

2 个答案:

答案 0 :(得分:1)

我可以通过覆盖NSViewController的viewWillAppear方法来设置视图控制器的表示对象,该方法似乎是在将文档实例设置为窗口文档后调用的。

- (void)viewWillAppear {
    [super viewWillAppear];

    // Set up the document as the data source
    NSLog(@"viewWillAppear");
    NSWindow *myWindow = [[self view] window];
    NSWindowController *myWindowController = [myWindow windowController];
    CharacterSheetDocument *myDocument = [myWindowController document];
    [self setRepresentedObject: [myDocument characterData]];
}

我不知道这是否是最干净的方法,但确实有效。

对于视图控制器来说,不仅要遍历嵌套的getter系列来查找模型对象,而且要了解文档子类的所有内容,这似乎有点笨拙。

答案 1 :(得分:1)

当我遇到这个问题时,我一直在寻找如何做到这一点。在ViewController类的viewWillAppear方法中执行此操作(由wolfteeth建议)使ViewController依赖于Document对象,这对我来说似乎是倒退。

最好在Document类的makeWindowControllers方法中执行此操作,如下所示:

override func makeWindowControllers() {
    // Returns the Storyboard that contains your Document window.
    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as! NSWindowController
    self.addWindowController(windowController)

    // Set represented object of ViewController
    if let viewController: ViewController = windowController.contentViewController as! ViewController? {
        viewController.representedObject = self.model
    }
}

此代码段假定您在Document类中有一个名为“model”的属性,该属性引用ViewController所代表的模型对象。