2

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

  1. 根据最后一个活动窗口的位置定位和调整大小。
  2. 如果最后一个活动窗口仍然可见,那么新窗口应该被级联,这样它就不会直接重叠。

但是,当使用情节提要时,这还没有完成。请参阅测试项目

4

3 回答 3

6

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

  1. 在情节提要中选择窗口控制器
  2. 选择身份检查员
  3. 添加具有以下值的新用户定义运行时属性:
  • 关键路径:shouldCascadeWindows
  • 类型:布尔值
  • 值:勾选

更新: 如果您移动第一个窗口,新窗口将从屏幕中间开始级联,而不是在第一个窗口下方。要解决这个问题:

  1. 选择窗口
  2. 在属性检查器中给它一个自动保存名称

这也应该在下一个窗口加载和应用程序启动时保持窗口位置和大小。

于 2017-05-01T20:39:51.400 回答
4

级联 Windows 问题

问题之一是与 xib 不同的情节提要可以包含NSWindowController并且 Interface Builder 不能正确序列化它。

-initWithWindow:-initWithWindowNibName:和朋友们shouldCascadeWindows设置YES

当 aNSWindowController从情节提要通过-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]or-[NSWindow frameAutosaveName]似乎只起作用。它随机使用初始窗口位置。

窗口大小问题

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

解决方法

使用包含空的 xibNSWindow并将情节提要中的视图控制器添加到窗口中-[NSDocument windowControllerDidLoadNib:-[NSDocument addWindowController:]窗口中。

于 2016-03-06T13:13:01.200 回答
2

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

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

我认为这更多的是运行时约束,然后是故事板 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: 
    

因此,只有创建的第一个窗口才会获得“SaveMe”自动保存名称。对于以下所有窗口,永远不会设置该值。

我的结论是你不能用它frameAutosaveName来复制 Safari 的行为。相反,您必须手动执行一些操作。我不确定示例项目中使用的方法是否是最好的方法,但我认为无论您使用的是 xibs 还是情节提要,Safari 的行为都至少需要一些手动工作。

于 2016-03-06T15:51:26.047 回答