基于文档的应用程序自动保存故事板

时间:2016-03-06 13:13:01

标签: macos cocoa nsdocument nsstoryboard

在基于文档的应用程序中,使用XIB文件,在创建新窗口时,其行为是:

  1. 根据最后一个活动的位置定位和调整大小 窗口。
  2. 如果最后一个活动窗口仍然可见,那么新的     窗口应该级联,所以它不会直接重叠。
  3. 然而,当使用故事板时,这还没有完成。请参阅测试enter image description here

3 个答案:

答案 0 :(得分:5)

您可以在故事板中的窗口控制器上设置shouldCascadeWindows:

  1. 在故事板中选择窗口控制器
  2. 选择身份检查员
  3. 使用以下值添加新的用户定义的运行时属性:
    • 关键路径:shouldCascadeWindows
    • 类型:布尔值
    • 价值:已检查

    <强>更新 如果移动第一个窗口,新窗口将从屏幕中间开始,而不是在第一个窗口下方。解决它:

    1. 选择窗口
    2. 在属性检查器中为其指定自动保存名称
    3. 这也应该在下一个窗口加载和应用程序启动时保持窗口位置和大小。

答案 1 :(得分:2)

级联Windows问题

其中一个问题是,与xib不同的故事板可以包含NSWindowController,而Interface Builder也不会将其序列化。

-initWithWindow:-initWithWindowNibName:和朋友将shouldCascadeWindows设置为YES

通过NSWindowController从故事板加载-initWithCoder:时,shouldCascadeWindowsNO。 (OS X 10.11)

根据我的测试,需要在初始化程序中设置此属性。在-[NSDocument addWindowController:]中设置它并不起作用。 (OS X 10.11)

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

见rdar:// 47350352

窗口位置问题

使用-[NSWindowController windowFrameAutosaveName]-[NSWindow frameAutosaveName]似乎有时只能工作。随机地使用初始窗口位置。

窗口大小问题

即使级联窗口位置设置正确,也不会将大小设置为为帧保存的大小。我使用defaults read window.autosavename.test1验证了已保存的框架。在每次测试之前,我都会运行defaults delete window.autosavename.test1以获得干净状态。

解决方法

使用包含空NSWindow的xib,并将-[NSDocument windowControllerDidLoadNib:-[NSDocument addWindowController:]中的故事板中的视图控制器添加到窗口中。

答案 2 :(得分:1)

我认为答案可能是,即使多个NSSplitView可能共享相同的frameAutosaveName,也不可能让多个窗口共享相同的autosaveName

我刚刚尝试创建另一个基于NSDocument的项目,但这次我使用的是xib而不是故事板。行为更好(默认情况下shouldCascadeWindows处于启用状态)。但是当涉及多个窗口时,新窗口定位仍然会中断。

我认为这更多是运行时约束,然后是storyboard vrs xib问题。这是我在Xcode生成的默认非故事板NSDocument项目中所做的测试:

  1. 在界面构建器中设置窗口自动保存名称。

  2. windowControllerDidLoadNib修改为如下所示:

    - (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. 然后(创建一些窗口后)这是我看到的输出:

    Listing frameAutosaveName for all windows:
    Untitled: SaveMe
    Untitled 2: 
    Untitled 3: 
    Untitled 4: 
    Untitled 5: 
    Window: 
    
  4. 因此,只有创建的第一个窗口才会获得“SaveMe”自动保存名称。对于以下所有窗口,永远不会设置该值。

    我的结论是你不能使用frameAutosaveName来复制Safari的行为。相反,你必须手动做一些事情。我不确定example project中使用的方法是否是最佳方法,但我认为无论您使用的是xib还是故事板,Safari的行为至少需要一些手动工作。