【问题标题】:NSWindow with NSWindowTitleVisibilityNone saving incorrect frame to user defaults?带有 NSWindowTitleVisibilityNone 的 NSWindow 将不正确的帧保存到用户默认值?
【发布时间】:2015-01-08 22:02:45
【问题描述】:

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

在重新启动应用程序之前一切正常。每次应用程序启动时,窗口都会根据从默认窗口样式 (NSWindowTitleVisible) 切换到新样式 (NSWindowTitleHidden) 所节省的空间来增长。因此,重新启动应用程序 5 到 6 次将使窗口与菜单栏和停靠栏齐平,具体取决于最初选中复选框时窗口的大小。

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

谢谢!

【问题讨论】:

  • 他们还没有解决这个问题真是太疯狂了,我遇到了同样的问题,在我的窗口控制器的 awakeFromNib 方法中设置了 [self.window setTitleVisibility:NSWindowTitleHidden];。也许我们做错了什么……
  • OSX 10.10 的日历应用程序具有这种特殊外观并且没有问题。

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


【解决方案1】:

pointumhttps://openradar.appspot.com/18510665 上发布了一个更好(并且已确认有效)的解决方案:

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

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

【讨论】:

    【解决方案2】:

    尝试在用户定义的运行时属性

    中将titleVisibility属性设置为数字1

    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 的键值编码不兼容

    【讨论】:

      【解决方案3】:

      目前的简单解决方法是手动保存和恢复窗口的框架,我是这样做的:

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

      - (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];
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-25
        • 2023-04-04
        • 1970-01-01
        相关资源
        最近更新 更多