将Subview添加到NSWindow的标题栏

28

我想创建一个自定义的窗口工具栏,但是不使用实际的NSToolbar(因为它在某些情况下不能满足我的需求,并且我无法按照我想要的方式进行样式设置),因此需要将子视图添加到窗口标题栏中。

它应该看起来像这样:自定义工具栏截图

一种可能的方法是:

[[[_window contentView] superview] addSubview:_titlebarView];

但是这种方法存在问题,会在Yosemite上引发警告 (NSWindow warning: adding an unknown subview: <NSView: 0x608000122b20>),所以这似乎不是正确的方法。

目前我将工具栏视图添加到标题栏视图中:

[[[_window standardWindowButton:NSWindowCloseButton]
    superview] addSubview:_titlebarView];

但这样也感觉不对。

由于我的应用程序只针对OS X 10.10(Yosemite),因此我可以使用仅适用于Yosemite的API,因此我查看了 NSTitlebarAccessoryViewController 并成功地将其子类化,并使用 NSWindowaddTitlebarAccessoryViewController: 方法。采用这种方法仍然存在一个问题,即 layoutAttribute 的可能值为:

  • NSLayoutAttributeBottom
    将视图添加到窗口标题栏底部,同时保留视图的高度。
  • NSLayoutAttributeRight
    将视图添加到窗口标题栏右侧,将视图修剪为标题栏的高度。

NSLayoutAttributeBottom 对我来说不合适,因为我需要将东西放在窗口标题栏顶部(请参见上面的截图)并居中交通灯。 NSLayoutAttributeRight 恰好是我所需的,但我找不到一种方法来增加标题栏的高度,使视图被裁剪为标题栏高度,这对我没有用。(注意:使用纹理窗口并更改内容边框无效,因为它不会更改实际标题栏高度)

有什么推荐的方法吗?如果可以拥有大于默认标题栏的视图,则我更愿意使用官方API并使用AccessoryViewController方法。


1
这真让我烦恼... - SevenBits
你可以继续使用你目前正在使用的方法...但是它会生成一个警告。 - SevenBits
3
我知道我可以使用它,但发布说明中有一条明确的注释: “这样做的应用程序需要修复此问题,否则阻止了10.10上的新功能正常工作。”在Mac OS X开发人员发布说明上提到。 - ePirat
@ePirat 当您将toolbarView添加到titlebarView中时,它是否会动态调整titlebar的高度,还是无论您添加的视图的内容高度如何,titlebar的高度都是固定的? - Sam
@ePirat 当我使用NSTitlebarAccessoryViewController和NSLayoutAttribute.Right时,它会填充整个标题栏!你怎么让它不这样做?但是,我确认它也将高度剪裁为现有标题栏的高度。苹果公司在设计这个API时在想什么呢? - Sam
显示剩余6条评论
4个回答

6

这只是一个 NSToolBar。在 Yosemite 中,当 window.title.titleVisibility = .Hidden 时,NSToolBar 将成为标题栏。


1
正如我在我的问题中所提到的,出于样式原因,我不想使用NSToolBar,除非有一种方法可以像视图一样使用它,并能够在界面构建器中完全设计它(并使用自动布局)。我认为这是不可能的。 - ePirat

4

WAYAppStoreWindow可能能够满足您的需求。它专门构建以避免在Yosemite中出现子视图警告,指定自定义窗口标题栏高度并向标题栏添加子视图。


谢谢,我已经看过了,但是不知道如何添加子视图。 - ePirat
4
将子视图添加到标题栏视图中,相当于执行[[[_window standardWindowButton:NSWindowCloseButton] superview] addSubview:_customTitlebarView]; - ePirat
在El-Capitan中,如果显示一个sheet,交通灯会重置它们的位置。当处于全屏模式时,问题甚至更多。啊啊啊,现在这变得如此困难了。 - strangetimes
1
为什么苹果没有提供清晰明确的API,WAYAppStoreWindow或INAppStoreWindow的问题在于它执行了本应该是苹果的代码。我的“INAppStoreWindow”有一个好的副作用,就是每次运行后窗口大小都会增加... - Klajd Deda

1

谢谢 @ePirat

将子视图添加到标题栏视图中,与执行以下操作相同

[[[_window standardWindowButton:NSWindowCloseButton] superview] addSubview:_customTitlebarView];

1
那其实并不是一个很有建设性的答案,因为它并没有帮助回答我的问题。这种方法虽然可行,但感觉像是在偷懒,而且苹果应用商店可能不会喜欢。(同时,在全屏模式下也存在一些问题) - ePirat

0
将你的窗口分配给self视图。 然后使用frame添加子视图 最后提供所需的功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接