Macos 基于文档的应用程序自动保存与情节提要

Macos 基于文档的应用程序自动保存与情节提要,macos,cocoa,nsdocument,nsstoryboard,Macos,Cocoa,Nsdocument,Nsstoryboard,在基于文档的应用程序中,使用XIB文件创建新窗口时,其行为为: 根据最后一个活动的位置进行定位和调整大小 窗户 如果最后一个活动窗口仍然可见,则新窗口 窗口应该层叠,这样它就不会直接重叠 但是,当使用故事板时,这并没有完成。请参阅测试。级联窗口问题 其中一个问题是与XIB不同的故事板可能包含NSWindowController,而Interface Builder没有正确序列化它 -initWithWindow:,-initWithWindowNibName:和好友设置应将Windows级联为是

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

  • 根据最后一个活动的位置进行定位和调整大小 窗户
  • 如果最后一个活动窗口仍然可见,则新窗口 窗口应该层叠,这样它就不会直接重叠
  • 但是,当使用故事板时,这并没有完成。请参阅测试。

    级联窗口问题 其中一个问题是与XIB不同的故事板可能包含
    NSWindowController
    ,而Interface Builder没有正确序列化它

    -initWithWindow:
    -initWithWindowNibName:
    和好友设置
    应将Windows
    级联为

    当通过
    -initWithCoder:
    从情节提要加载
    NSWindowController
    时,
    应将Windows
    级联为
    。(操作系统X 10.11)

    根据我的测试,需要在初始值设定项中设置此属性。在
    -[NSDocument addWindowController:
    中设置它无效。(操作系统X 10.11)

    看rdar://47350352

    窗口位置问题 使用
    -[NSWindowController windowFrameAutosaveName]
    -[NSWindow frameAutosaveName]
    似乎只是偶尔起作用。它随机使用初始窗口位置

    窗口大小问题 即使级联窗口位置设置正确,也不会将大小设置为为为帧保存的大小。我用
    默认读取窗口.autosavename.test1
    验证了保存的帧。同样在每次测试之前,我运行
    默认删除window.autosavename.test1
    以获得干净状态

    变通办法
    使用包含空
    NSWindow
    的xib,并在
    -[NSDocument WindowControllerdLoadNib:
    -[NSDocument addWindowController:]中从情节提要添加视图控制器
    切换到窗口。

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

    我刚刚尝试创建另一个基于NSDocument的项目,但这次我使用了xib而不是故事板。行为更好(
    shouldCascadeWindows
    默认为打开)。但当涉及多个窗口时,新窗口定位仍然会出现故障

    我认为这更像是一个运行时约束,而不是故事板vrs xib问题。以下是我刚刚在Xcode生成的默认非故事板NSDocument项目中进行的测试:

  • 在界面生成器中设置窗口自动保存名称

  • 修改
    WindowControllerIDloadNib
    如下所示:

    - (void)windowControllerDidLoadNib:(NSWindowController *)aController {
        [super windowControllerDidLoadNib:aController];
    
        NSLog(@"Listing frameAutosaveName for all windows:");
        for (NSWindow *each in [NSApp windows]) {
            NSLog(@"%@: %@", each.title, each.frameAutosaveName);
        }
    }
    
  • 然后(在创建了多个窗口之后),我看到的输出是:

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


    我的结论是,您不能使用
    frameAutosaveName
    复制Safari的行为。相反,您必须手动执行某些操作。我不确定中使用的方法是否是最好的方法,但我认为至少需要一些手动操作来实现Safari的行为,无论您使用的是XIB还是故事板。

    您可以设置shouldCasca情节提要中窗口控制器上的窗口:

  • 在情节提要中选择窗口控制器
  • 选择标识检查器
  • 使用以下值添加新的用户定义的运行时属性:
    • 关键路径:shouldCascadeWindows
    • 类型:布尔型
    • 值:选中

    更新: 如果你移动第一个窗口,新的Windows级联从屏幕中部开始,而不是在第一个窗口下面。
  • 选择窗口
  • 在属性检查器中,为其指定一个自动保存名称

  • 这也应该在下次窗口加载和应用程序启动时保留窗口位置和大小。

    Hm…使用通过
    -[NSDocument windowNibName]加载的xib
    以及在xib窗口中设置的autosave名称在我测试每个窗口时,您的日志代码会为每个窗口报告正确的frameAutosaveName。您是否介意将示例项目发布到某个地方。也许我只是在测试中做了一些愚蠢的事情,但我“认为”和你描述的差不多。在这个例子中,我用的是上一次更改的窗口大小,但不是X,Y位置。你在OS X 10.11.3上吗?你是对的。我测试了一个如此大的窗口,我没有注意到,尽管它只是使用了“找一个合适的地方”批准。使用10.11.4测试版。windows frameAutosaveName如何?
    Listing frameAutosaveName for all windows:
    Untitled: SaveMe
    Untitled 2: 
    Untitled 3: 
    Untitled 4: 
    Untitled 5: 
    Window: