在基于文档的 OS X 应用程序中的 NSViewController 上设置 representedObject
Set representedObject on an NSViewController in a document-based OS X application
我正在开发一个简单的 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 知道它的 window/WindowController,但我不确定如何找到ViewController 来自 类.
我想知道执行此操作的惯用 Xcode/Apple 方法。无论是通过 Storyboard 视图还是在我的代码中以编程方式实现。
我还想尽可能避免将代码耦合得太紧。
我能够通过覆盖 NSViewController 的 viewWillAppear 方法来设置视图控制器的表示对象,该方法似乎是在将文档实例设置为 window 文档之后调用的。
- (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 来查找模型对象,而且还了解文档子类的所有信息,这似乎有点笨拙。
当我 运行 回答这个问题时,我只是想自己解决这个问题。在 ViewController class 的 viewWillAppear 方法中执行此操作(如 wolfteeth 所建议)使 ViewController 依赖于 Document 对象,这对我来说似乎是倒退的。
最好在文档 class 的 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
}
}
此代码片段假定您的文档 class 中有一个名为 "model" 的 属性,它引用了您的 ViewController 代表的模型对象。
我正在开发一个简单的 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 知道它的 window/WindowController,但我不确定如何找到ViewController 来自 类.
我想知道执行此操作的惯用 Xcode/Apple 方法。无论是通过 Storyboard 视图还是在我的代码中以编程方式实现。
我还想尽可能避免将代码耦合得太紧。
我能够通过覆盖 NSViewController 的 viewWillAppear 方法来设置视图控制器的表示对象,该方法似乎是在将文档实例设置为 window 文档之后调用的。
- (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 来查找模型对象,而且还了解文档子类的所有信息,这似乎有点笨拙。
当我 运行 回答这个问题时,我只是想自己解决这个问题。在 ViewController class 的 viewWillAppear 方法中执行此操作(如 wolfteeth 所建议)使 ViewController 依赖于 Document 对象,这对我来说似乎是倒退的。
最好在文档 class 的 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
}
}
此代码片段假定您的文档 class 中有一个名为 "model" 的 属性,它引用了您的 ViewController 代表的模型对象。