在标准NSWindow上创建自定义标题栏

Jos*_*rth 7 cocoa objective-c nstableview nswindow nsscrollview

我一直在努力为我的菜单栏应用程序构建一个特定的外观.

在此输入图像描述

我一直在使用一个NSWindowNSBorderlessWindowMask式面膜和设置[window setOpaque:NO][window setBackgroundColor:[NSColor clearColor]].这给了我一个空白的画布,非常适合标题栏.

现在我遇到了基于视图的问题,NSTableView我正在使用该列表.如何将NSTableCellViews 剪裁到窗口的圆角?

我开始只是有一个自定义视图包装NSTableView,用圆角绘制背景.[view addClip:path]虽然使用不剪辑子视图.

我也试过用[view setWantsLayer:YES]面具.这很有效,但桌面视图单元格会偶尔出现故障.似乎拥有一个NSScrollView图层的孩子是一个已知的问题:

http://i.stack.imgur.com/JmhjD.png

我当前的视图结构类似于:

NSWindow
- MyTitleBarView
- MyBackgroundView
  - NSScrollView
    - NSTableView
Run Code Online (Sandbox Code Playgroud)

Jos*_*rth 1

我找到了一种方法来做到这一点:

诀窍是保持窗口样式为默认样式而不是设置NSBorderlessWindowMask。然后您可以将自定义标题栏视图添加到窗口的主题框架中,如下所示:

NSView *themeFrame = [[window contentView] superview];
NSView *firstSubview = [[themeFrame subviews] objectAtIndex:0];
[titleBarView setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)];
[themeFrame addSubview:titleBarView positioned:NSWindowBelow relativeTo:firstSubview];
Run Code Online (Sandbox Code Playgroud)

这基本上只是将您的自定义标题栏视图放在标准标题栏的顶部。您可能需要对视图框架和窗口按钮进行一些重新调整。有关这方面的一些代码示例,请参阅INAppStoreWindow 。

INAppStoreWindow项目表示该方法不使用任何私有API,因此可以在App Store上使用。

如果您需要窗口透明,则可以在窗口上进行以下设置:

[window setOpaque:NO];
[window setBackgroundColor:[NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
Run Code Online (Sandbox Code Playgroud)

  • 嗯,它可以工作,但在 OS X 10.10 中,这种方法会导致警告“NSWindow 警告:添加未知的子视图”。苹果文档说:“这些视图将用一个名为 NSTitlebarAccessoryViewController 的新 NSViewController 子类进行包装,并使用“titlebarAccessoryViewControllers”API 添加到窗口中。” https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/ (2认同)