NSDocument:如何保存和恢复文档的 window 位置?
NSDocument: how do you save & restore a document's window position?
我有一个基于 NSDocument
的应用程序,我希望在重新打开文档时保存和恢复我的 window 位置。 Apple 关于此的文档非常少,但我能够拼凑的是,在某些时候,应用程序中的某些内容需要调用 NSWindow.setFrameUsingName()
和 NSWindow.setFrameAutosaveName()
.
我还没有完全弄清楚这需要在什么时候发生,以及需要做什么才能做到这一点。例如,这根本不起作用:
// 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")
}
我已经阅读了各种不同的文档或论坛答案,指出 awakeFromNib()
是另一个领域,但我也无法让它发挥作用。
我也很困惑/担心这会以某种方式受到自动布局或我在 Interface Builder 中做错的事情的影响 - 例如,这是我的 window 在 IB 中的设置方式:
我不是特别希望我的 window 居中,但其他选项似乎将其锁定在固定的水平或固定的垂直位置,我也不太想要。让我的 window 居中的一个副作用是我的文档 windows 不再级联,我不想也似乎不能停止发生(请注意 windowController.shouldCascadeWindows = true
也无济于事).
所以 - 这是怎么回事?我发现关于这个主题的知识特别不清楚或具有误导性,并且可能已经过时 Cocoa 开发 2015,所以现代复习一下会很棒。
第 1 步:在 IB 中,为 window 指定一个自动保存名称。
第2步:没有第2步
为 window 框架设置自动保存名称的最简单的地方可能是在您的 NSDocument 实现中。
如果您将 makeWindowControllers()
作为实现的一部分进行覆盖,您将手动创建 window 控制器,因此可以在那里设置名称:
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)
}
如果您通过覆盖 windowNibName
来实例化您的文档 window,您应该改为覆盖方法 windowControllerDidLoadNib(_:)
,以在 window 上设置自动保存名称。我没有测试过这段代码,但我认为它会起作用:
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)
}
我有一个基于 NSDocument
的应用程序,我希望在重新打开文档时保存和恢复我的 window 位置。 Apple 关于此的文档非常少,但我能够拼凑的是,在某些时候,应用程序中的某些内容需要调用 NSWindow.setFrameUsingName()
和 NSWindow.setFrameAutosaveName()
.
我还没有完全弄清楚这需要在什么时候发生,以及需要做什么才能做到这一点。例如,这根本不起作用:
// 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")
}
我已经阅读了各种不同的文档或论坛答案,指出 awakeFromNib()
是另一个领域,但我也无法让它发挥作用。
我也很困惑/担心这会以某种方式受到自动布局或我在 Interface Builder 中做错的事情的影响 - 例如,这是我的 window 在 IB 中的设置方式:
我不是特别希望我的 window 居中,但其他选项似乎将其锁定在固定的水平或固定的垂直位置,我也不太想要。让我的 window 居中的一个副作用是我的文档 windows 不再级联,我不想也似乎不能停止发生(请注意 windowController.shouldCascadeWindows = true
也无济于事).
所以 - 这是怎么回事?我发现关于这个主题的知识特别不清楚或具有误导性,并且可能已经过时 Cocoa 开发 2015,所以现代复习一下会很棒。
第 1 步:在 IB 中,为 window 指定一个自动保存名称。
第2步:没有第2步
为 window 框架设置自动保存名称的最简单的地方可能是在您的 NSDocument 实现中。
如果您将 makeWindowControllers()
作为实现的一部分进行覆盖,您将手动创建 window 控制器,因此可以在那里设置名称:
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)
}
如果您通过覆盖 windowNibName
来实例化您的文档 window,您应该改为覆盖方法 windowControllerDidLoadNib(_:)
,以在 window 上设置自动保存名称。我没有测试过这段代码,但我认为它会起作用:
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)
}