简体   繁体   中英

NSDocument: how do you save & restore a document's window position?

I have a NSDocument -based app, and I'd like my window positions to be saved and restored when re-opening documents. Apple's documentation on this is pretty sparse, but what I've been able to piece together is that at some point, something in the app needs to call NSWindow.setFrameUsingName() and NSWindow.setFrameAutosaveName() .

What I haven't quite figured out is what point this needs to happen at, and what things need to do this. For example, this doesn't work at all:

// In my NSDocument class    
override func windowControllerDidLoadNib(aController: NSWindowController) {
    super.windowControllerDidLoadNib(aController)

    // Add any code here that needs to be executed once the windowController has loaded the document's window.
    aController.window?.setFrameUsingName("MainWindow")
    aController.window?.setFrameAutosaveName("MainWindow")
}

I've read various different pieces of documentation or forum answers that point to awakeFromNib() to be another area to do this, but I can't get that to work either.

I'm also confused / worried that this is somehow being affected by Auto Layout or something I've done wrong in Interface Builder - for example, this is how my window is set up in IB:

I don't particularly want my window centered, but the other options seem to lock it in place in fixed horizontal or fixed vertical positions, which I also don't really want. A side effect of having my window be centered is that my document windows no longer cascade, which I neither want nor can seem to stop from happening (note that windowController.shouldCascadeWindows = true isn't helping either).

So - what's going on here? I'm finding knowledge on this topic to be particularly unclear or misleading, and likely out of date for Cocoa development 2015, so a modern refresher on this would be great.

Step 1: In IB, give the window an autosave name.

在此输入图像描述

Step 2: There is no step 2.

The easiest place to set the name of the autosave name for the window frame is probably in your implementation of NSDocument.

If you override makeWindowControllers() as part of the implementation, you are creating the window controller(s) manually, and thus can set the name there:

override func makeWindowControllers() {
    let storyboard = NSStoryboard(name: NSStoryboard.Name("MyDocumentStoryboard"), bundle: nil)
    let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("MyDocument Window Controller")) as! MyDocumentWindowController

    // this assumes you have a stored property or a computed property `someUniqueIdentifier` that is as unique as possible for your document
    // and that you store on disk together with the rest of the document properties
    windowController.windowFrameAutosaveName = NSWindow.FrameAutosaveName(rawValue: someUniqueIdentifier)

    self.addWindowController(windowController)
}

If you instantiate your document window by overriding windowNibName , you should instead override the method windowControllerDidLoadNib(_:) , to set the autosave name on the window. I have not tested this code, but I assume it will work:

func windowControllerDidLoadNib(_ windowController: NSWindowController) {
    // this assumes you have a stored property or a computed property `someUniqueIdentifier` that is as unique as possible for your document
    // and that you store on disk together with the rest of the document properties
    windowController.windowFrameAutosaveName = NSWindow.FrameAutosaveName(rawValue: someUniqueIdentifier)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM