[英]Document-Based App autosave with storyboards
In Document-Based Apps, using XIB files, when a new window is created its behaviour is: 在基于文档的应用程序中,使用XIB文件创建新窗口时,其行为是:
However when using a storyboard this isn't done. 但是,使用情节提要板时并不会这样做。 See test project .
请参阅测试项目 。
You can set shouldCascadeWindows on the window controller in your storyboard: 您可以在情节提要中的窗口控制器上设置shouldCascadeWindows:
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:
要解决这个问题:
This should also persist window location and size on the next window load and application launch. 在下一次加载窗口和应用程序启动时,这还将保留窗口的位置和大小。
One of the problems is that storyboards unlike xibs can include the NSWindowController
and Interface Builder doesn't serialize it right. 问题之一是与xibs不同的情节提要可以包含
NSWindowController
而Interface Builder不能正确序列化它。
-initWithWindow:
, -initWithWindowNibName:
and friends set shouldCascadeWindows
to YES
. -initWithWindow:
,- -initWithWindowNibName:
和朋友将shouldCascadeWindows
设置为YES
。
When a NSWindowController
is loaded from a storyboard via -initWithCoder:
, shouldCascadeWindows
is NO
. 通过
shouldCascadeWindows
-initWithCoder:
从情节shouldCascadeWindows
加载NSWindowController
, shouldCascadeWindows
为NO
。 (OS X 10.11) (作业系统X 10.11)
Based on my tests, this property needs to be set in the initializer. 根据我的测试,需要在初始化程序中设置此属性。 Setting it in
-[NSDocument addWindowController:]
didn't work. 在
-[NSDocument addWindowController:]
进行设置无效。 (OS X 10.11) (作业系统X 10.11)
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self)
{
self.shouldCascadeWindows = YES;
}
return self;
}
See rdar://47350352 参见rdar:// 47350352
Using -[NSWindowController windowFrameAutosaveName]
or -[NSWindow frameAutosaveName]
seems only to work sometimes. 有时仅使用
-[NSWindowController windowFrameAutosaveName]
或-[NSWindow frameAutosaveName]
。 Randomly it uses the initial window position. 它随机使用初始窗口位置。
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
. 我使用
defaults read window.autosavename.test1
验证了保存的帧。 Also before each test I run defaults delete window.autosavename.test1
for a clean state. 同样,在每次测试之前,我都会运行
defaults delete window.autosavename.test1
以保持干净状态。
Use a xib containing a empty NSWindow
and add the view controllers from the storyboard in -[NSDocument windowControllerDidLoadNib:
or -[NSDocument addWindowController:]
to the window. 使用包含空
NSWindow
的xib,然后从-[NSDocument windowControllerDidLoadNib:
或-[NSDocument addWindowController:]
的情节提要中将视图控制器添加到窗口。
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
. 我认为答案可能是,它只是没有可能有多个窗口共享同一个
frameAutosaveName
即使它可能有多个NSSplitView共享相同的autosaveName
。
I just tried creating another NSDocument based project, but this time I used xib's instead of a storyboard. 我只是尝试创建另一个基于NSDocument的项目,但是这次我使用xib而不是一个故事板。 The behavior is better (
shouldCascadeWindows
is on by default). 行为会更好(默认情况下应
shouldCascadeWindows
)。 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. 我认为这更多的是运行时约束,那么这是情节提要vrs xib问题。 Here's a test I just did in the default non storyboard NSDocument project generated by Xcode:
这是我刚刚在Xcode生成的默认非故事板NSDocument项目中进行的测试:
Set window autosave name in interface builder. 在界面生成器中设置窗口自动保存名称。
Modify windowControllerDidLoadNib
to look like this: 修改
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); } }
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. 因此,只有第一个创建的窗口会获得“ SaveMe”自动保存的名称。 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. 我的结论是,您无法使用
frameAutosaveName
复制Safari的行为。 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.
我不确定示例项目中使用的方法是否是最佳方法,但是我认为,无论您使用的是xibs还是情节提要,Safari的行为至少需要一些手动工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.