NSWindowController使用Storyboard自动保存

时间:2014-08-06 00:00:20

标签: xcode macos cocoa storyboard osx-yosemite

我有一个Swift应用程序正在启动一个简单的NSWindow,如下所示:

func applicationDidFinishLaunching(notification: NSNotification!) {
    let storyboard = NSStoryboard(name: "MainStoryboard", bundle: NSBundle.mainBundle())
    windowController = storyboard.instantiateInitialController() as? NSWindowController
    windowController?.showWindow(self)
}

这很好用,我的应用程序启动并出现窗口。 然而:大小始终相同。

在故事板中,我指定了Autosave名称:

MainStoryboard

另请注意,Restorable复选框已选中。

但无论如何,窗口每次都会出现相同的大小。这一直是"刚刚工作"在过去,所以我无法判断这是一个错误,还是我错过的一个错误。在手动实例化和显示窗口时,自动保存是否自动适用于故事板?

3 个答案:

答案 0 :(得分:28)

这似乎是一个Xcode错误。我可以通过手动设置NSWindowController windowFrameAutosaveName属性来解决此问题:

windowController?.windowFrameAutosaveName = "Main App Window"

但是......如果该属性设置为不同值而不是Interface Builder中显示的值,这仅适用于我。如果它以编程方式设置为与IB中使用的值相同,则不起作用。

因此,在IB中,自动保存名称留给MainAppWindow,并以编程方式将其设置为Main App Window

答案 1 :(得分:3)

我不知道是否有更好的方法,但问题是当 AutosaveName在Interface Builder中设置时,窗口是通过Segue打开的,窗口在预定位置打开并保存框架,覆盖上次保存的框架...

如果您有一个预定位置到屏幕中心,每次打开窗口时,它将显示在中心,并保存位置。

为避免这种情况,我在窗口控制器(不在IB中)中设置自动保存名称恢复已保存的帧后设置:

class MyWindowController: NSWindowController {
    override func windowDidLoad() {
        super.windowDidLoad()

        let thewindow = window as! NSWindow

        /// restore position
        thewindow.setFrameUsingName("MyWindow")
        self.windowFrameAutosaveName = "MyWindow"
    }
}

答案 2 :(得分:1)

为了满足接受的答案和注释中确定的两个条件,对窗口控制器进行子类化似乎可行。然后,您可以避免在代码中为每个窗口控制器唯一地设置此属性,而只需指定情节提要的窗口自动保存属性(并设置窗口控制器的子类)即可。

WindowController的windowFrameAutosaveName必须是

  1. 不是空白
  2. 不同于Window的frameAutosaveName
class AutoFrameSavingWindowController: NSWindowController
{
    override func awakeFromNib() {
        if let autosaveName = window?.frameAutosaveName {
            windowFrameAutosaveName = autosaveName + " temp"
            }
        }
    }
}