Mac App Storyboard - Access Document in NSViewController

前端 未结 3 1371
旧巷少年郎
旧巷少年郎 2021-02-12 12:08

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 NSViewCon

相关标签:
3条回答
  • 2021-02-12 12:36

    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).

    0 讨论(0)
  • 2021-02-12 12:36

    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.

    0 讨论(0)
  • 2021-02-12 12:43

    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

    0 讨论(0)
提交回复
热议问题