NSWindow与NSWindowTitleVisibilityNone将错误的帧保存到用户默认值?

时间:2014-11-12 06:11:10

标签: objective-c frame nsuserdefaults nswindow osx-yosemite

我的应用程序有一个选项,允许用户在标准"全尺寸"之间进行选择。窗口标题栏/工具栏和" compact"标题栏/工具栏在NSWindow 10.10 API中提供。具体来说,我使用-titleVisibility方法设置NSWindowTitleVisibleNSWindowTitleHidden,具体取决于用户的偏好。如果用户检查" Compact Titlebar"复选框,NSWindowTitleHidden应用于窗口,否则,窗口使用默认样式。当复选框值更改时,该值将存储在应用程序的用户默认值中,并且窗口将更新/重新绘制。

在重新启动应用程序之前,一切都很有效。每次应用程序启动时,窗口都会通过从默认窗口样式(NSWindowTitleVisible)切换到新样式(NSWindowTitleHidden)来精确增加节省的空间。因此,重新启动应用程序5-6次将使窗口与菜单栏和扩展坞齐平,具体取决于最初检查复选框时窗口的大小。

换句话说,在设置属性时,NSUserDefaults中的窗口框架似乎没有更新。有没有解决方法,或者我只是忽略了什么?任何建议都会很有帮助。

谢谢!

3 个答案:

答案 0 :(得分:2)

尝试将titleVisibility属性设置为用户定义的运行时属性中的数字1

enter image description here

1是NSWindowTitleHidden

的对应值
typedef NS_ENUM(NSInteger, NSWindowTitleVisibility) {
    /* The default mode has a normal window title and titlebar buttons. */
    NSWindowTitleVisible  = 0,
    /* The always hidden mode hides the title and moves the toolbar up into the area previously occupied by the title. */
    NSWindowTitleHidden = 1,
} NS_ENUM_AVAILABLE_MAC(10_10);

然而,这会向控制台打印一条消息,抱怨 NSWindow在10.10之前的OS X版本上的关键titleVisibility 不符合键值编码

答案 1 :(得分:2)

pointum https://openradar.appspot.com/18510665发布了一个更好(并确认工作)的解决方案:

  

问题是系统在设置-[NSWindow setFrameUsingName:]之前使用titleVisibility恢复窗口大小。解决方案:

     
      
  1. 在Interface Builder中删除“自动保存名称”值。
  2.   
  3. 使用titleVisibility设置-[NSWindow setFrameAutosaveName:]后立即在代码中设置。
  4.   

答案 2 :(得分:0)

现在的简单修复是手动保存和恢复窗口的框架,以下是我的操作方法:

在您的app委托中,当应用程序终止时,保存窗口的框架

- (void)applicationWillTerminate:(NSNotification *)notification
{
    [[NSUserDefaults standardUserDefaults] setObject:NSStringFromRect(self.windowController.window.frame) forKey:@"WindowFrameKey"];
}

在窗口控制器的-awakeFromNib方法中,恢复帧

- (void)awakeFromNib
{
    if([NSWindow instancesRespondToSelector:@selector(setTitleVisibility:)])
    {
        // Hide Titlebar
        [self.window setTitleVisibility:NSWindowTitleHidden];

        NSString *winFrameString = [[NSUserDefaults standardUserDefaults] stringForKey:@"WindowFrameKey"];

        if(winFrameString != nil)
        {
            NSRect savedRect = NSRectFromString(winFrameString);

            if(!NSEqualRects(self.window.frame, savedRect))
            {
                [self.window setFrame:savedRect display:YES animate:NO];
            }
        }
    }