Document-Based App autosave with storyboards

喜欢而已 提交于 2021-01-21 10:29:33

问题


In Document-Based Apps, using XIB files, when a new window is created its behaviour is:

  1. Be positioned and sized based on the position of the last active window.
  2. If the last active window is still visible then the new window should be cascaded so it doesn't directly overlap.

However when using a storyboard this isn't done. See test project.


回答1:


You can set shouldCascadeWindows on the window controller in your storyboard:

  1. select the window controller in the storyboard
  2. select the identity inspector
  3. add a new User Defined Runtime Attribute with these values:
  • key path: shouldCascadeWindows
  • Type: boolean
  • Value: checked

Update: If you move the first window, new windows cascade starting in the middle of the screen not under the first window. To fix it:

  1. select the window
  2. in the attributes inspector give it an autosave name

This should also persist window location and size on the next window load and application launch.




回答2:


Cascaded Windows Problem

One of the problems is that storyboards unlike xibs can include the NSWindowController and Interface Builder doesn't serialize it right.

-initWithWindow:, -initWithWindowNibName: and friends set shouldCascadeWindows to YES.

When a NSWindowController is loaded from a storyboard via -initWithCoder:, shouldCascadeWindows is NO. (OS X 10.11)

Based on my tests, this property needs to be set in the initializer. Setting it in -[NSDocument addWindowController:] didn't work. (OS X 10.11)

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self)
    {
        self.shouldCascadeWindows = YES;
    }
    return self;
}

See rdar://47350352

Window Position Problem

Using -[NSWindowController windowFrameAutosaveName] or -[NSWindow frameAutosaveName] seems only to work sometimes. Randomly it uses the initial window position.

Window Size Problem

Even if the cascaded window position is set right, it never set the size to the one saved for the frame. I verified the saved frame with defaults read window.autosavename.test1. Also before each test I run defaults delete window.autosavename.test1 for a clean state.

Workaround

Use a xib containing a empty NSWindow and add the view controllers from the storyboard in -[NSDocument windowControllerDidLoadNib: or -[NSDocument addWindowController:] to the window.




回答3:


I think the answer might be that it's just not possible to have multiple windows share the same frameAutosaveName even though it is possible to have multiple NSSplitView share the same autosaveName.

I just tried creating another NSDocument based project, but this time I used xib's instead of a storyboard. The behavior is better (shouldCascadeWindows is on by default). But new window positioning still breaks down when multiple windows are involved.

I think this is more of a runtime constraint then it is storyboard vrs xib problem. Here's a test I just did in the default non storyboard NSDocument project generated by Xcode:

  1. Set window autosave name in interface builder.

  2. Modify windowControllerDidLoadNib to look like this:

    - (void)windowControllerDidLoadNib:(NSWindowController *)aController {
        [super windowControllerDidLoadNib:aController];
    
        NSLog(@"Listing frameAutosaveName for all windows:");
        for (NSWindow *each in [NSApp windows]) {
            NSLog(@"%@: %@", each.title, each.frameAutosaveName);
        }
    }
    
  3. And then (after creating a number of windows) this is the output that I see:

    Listing frameAutosaveName for all windows:
    Untitled: SaveMe
    Untitled 2: 
    Untitled 3: 
    Untitled 4: 
    Untitled 5: 
    Window: 
    

So only the first window created gets the "SaveMe" autosave name. For all the following windows the value is never set.

My conclusion is that you just can't use frameAutosaveName to replicate Safari's behavior. Instead you must do something manual. I'm not sure if the method used in the example project is the best way, but I think at least some manual work is needed for Safari's behavior no matter if you are using xibs or storyboards.



来源:https://stackoverflow.com/questions/35827239/document-based-app-autosave-with-storyboards

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!