我正在开发一个简单的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视图还是以我的代码中的编程方式。
如果可能的话,我还想避免过于紧密地耦合代码。
答案 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所代表的模型对象。