Xcode 9 storyboard window position autosave

Viewed 1418

I start new project in Xcode 9 (macOS Game with SceneKit technology). I got storyboard containing NSWindowController with NSWindow and related GameViewController with SCNView. Project runs fine (spins a plane).

Now in storyboard I set Autosave value to "MainWindow" for NSWindow, run project, resize window and then quit. I know that with Autosave set on quit window position will be saved using NSUserDefaults, so I check in Terminal:

$ defaults read com.koati.Bloks                                           ⏎
{
    "NSWindow Frame MainWindow" = "415 228 450 322 0 0 1280 777 ";
}

That's expected behaviour. Now I run project once again, but I see that window position is not restored. If in storyboard I remove GameViewController relation, then position is saved and restored correctly, so I suppose that GameViewController somehow influences window size and position. In older Xcode with XIBs there were no such problem.

EDIT: After some doing some tests, I now think it is not related to SceneKit at all, as replacing SCNView with NSView in NSViewController produces same results. So I think the problem is that NSViewController attached via Storyboard to NSWindow content influences window position and size.

Maybe some one knows how to fix this issue?

2 Answers

Strangely enough, this answer: https://stackoverflow.com/a/33707356/3736845 still applies, even in XCode9. After programmatic setup of autosave name (for Swift4 a bit different notation):

class MainWindowController: NSWindowController {

  override func windowDidLoad() {
    super.windowDidLoad()

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
    self.windowFrameAutosaveName = NSWindow.FrameAutosaveName.init(rawValue: "position")
  }
}

it started restoring positions on restart of the Application.

What I don't understand however is what's saved into defaults:

defaults read com.ne.TestWindowPosition
{
   "NSWindow Frame Position" = "510 428 901 322 0 0 1920 1177 ";
   "NSWindow Frame position" = "0 0 901 322 0 0 1920 1177 ";
}

I played a bit with the IB Window Autosave identifier - you see it appears as first line in the defaults ("Position") and it doesn't seem to be read properly on Application startup. After I added manual set of autosave name to "position" - it's changing, when I move the window.

This seems like a bug that's still in Xcode 10. Here's what worked for me (in Xcode 10, in a macOS Cocoa project using storyboards):

• No value set in the storyboard's window's autosave field.

• Use a custom window controller class as below.

import AppKit


class WindowController: NSWindowController {

    override func windowDidLoad() {
        super.windowDidLoad()
        //---------------------------------------------------------------------
        // Workaround for a bug in autosave default for window frame:
        window!.setFrameAutosaveName("position")
        // It has to be "position" here in code, and no value in storyboard.
        //---------------------------------------------------------------------
    }
}
Related