Mac App Storyboard - Access Document in NSViewController

好久不见. 提交于 2020-01-01 01:16:12

问题


I am currently fighting with NSDocument in a document based Storyboard based Cocoa Application (Objective C). Can anybody tell me how i can access the document in the NSViewController subclass?

I've tried to access it the following way - but the document is null:

[self.view.window.windowController document];

Thanks for your help!

Best regards Martin


回答1:


I was just wrestling with this myself. I started with the standard Yosemite template and was trying to use [self.view.window.windowController document] in -viewDidLoad. At that point, self.view.window is nil, so there's no way to get to the document.

The trick is to wait until -viewWillAppear. By the time it is called, self.view.window is populated and the document is available.

Sequence: -makeWindowControllers invokes -self addWindowController: with the storyboard's -instantiateControllerWithIdentifier: result. -addWindowController: triggers a call to the VC's -viewDidLoad before returning. Then, finally, -viewWillAppear is called (and the document is available).




回答2:


This does not directly address the question. But the Q&A link below shows how to access the data model in your document from NSControl objects using bindings, by utilising the preparedObject of the NSViewController.

https://developer.apple.com/library/content/qa/qa1871/_index.html

I set the representedObject for the NSViewController in Document.m as following:

- (void)makeWindowControllers {
    NSWindowController* wc = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"Document Window Controller"];
    NSViewController* vc = wc.contentViewController;
    vc.representedObject = self.model;

    [self addWindowController:wc];
}

Now representedObject of my ViewController is set to model. Assuming my model has a text property, I can bind any NSControl to that property through ViewController with keyPath: self.representedObject.text




回答3:


I know the original question was for Objective-C, but for others using Swift, protocols can help. The basic concept can be applied in Objective-C as well.

Instead of reaching back to the window controller, you could use dependency injection:

1) Create a document property on your window controller and any view controllers that need to access the document (or utilize the representedObject property that already exists). To make this easier, you could use a protocol to define the document property or to cast the representedObject property to your document type if you go that route. Make all the view controllers that need to access the document adopt this protocol.

protocol DocumentAccessing {
   var document: MyDocument? { get set } // could also use an implicitly unwrapped optional if the document is required to be set for the app to function
}

2) In the makeWindowControllers() method of your document subclass, after creating your window controller, set its document property to self (as this is the document).

- (void)makeWindowControllers {
     MyWindowController *windowController = MyWindowController()
     windowController.document = self;
     [self addWindowController:windowController];
}

3) Inside your window controller subclass, after you instantiate your view controllers, set the document property of the view controller to the window controller's document property.

4) Now by the time your view controller is loaded, it's document property should be populated.



来源:https://stackoverflow.com/questions/27702002/mac-app-storyboard-access-document-in-nsviewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!